【C++】类和对象(二)
耐心、韧性、体谅、宽容、包涵,都是爱的代名词。https://i-blog.csdnimg.cn/direct/211eddd9df0b4ff2932ea0b7d0935a4a.png
媒介
这是我自己学习C++的第三篇博客总结。后期我会继续把C++学习条记开源至博客上。
上一期条记是关于C++的类和对象,没看的同学可以已往看看:
【C++】类和对象(一)-CSDN博客https://csdnimg.cn/release/blog_editor_html/release2.3.8/ckeditor/plugins/CsdnLink/icons/icon-default.png?t=P1C7https://blog.csdn.net/hsy1603914691/article/details/143213525
初始化列表
1. 在调用构造函数时,成员变量的初始化通常有两种方式:一种是在构造函数体内进行赋值,另一种是通过初始化列表进行赋值。
2. 初始化列表的利用方法如下:以冒号开头,随后是一个由逗号分隔的成员变量列表,每个成员变量后面紧跟一对圆括号,括号中包罗该变量的初始值或初始化表达式。
3. 引用范例的成员变量,const修饰的成员变量,自定义范例的成员变量,必须放在初始化列表进行初始化,否则会编译报错。
4. C++11支持在成员变量声明时给缺省值,这个缺省值重要是给没有显示的在初始化列表初始化的成员利用的。
5. 只管利用初始化列表,因为那些你不在初始化列表初始化的成员也会走初始化列表。
6. 初始化列表按照成员变量在类中声明先后顺序进行初始化,与成员在初始化列表出现的先后顺序无关。故建议声明顺序和初始化列表顺序保持同等。
https://i-blog.csdnimg.cn/direct/fc358545ba2b42839a84110e0f405449.png
#include<iostream>
using namespace std;
class Time
{
public:
Time(int hour)
:_hour(hour)
{
cout << "Time()" << endl;
}
private:
int _hour;
};
class Date
{
public:
Date(const int& x, int year = 1, int month = 1, int day = 1)
:_year(year)
, _month(month)
, _day(day)
, _t(12)
, _ref(x)
, _n(1)
{}
void Print() const
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year = 10;//可以在声明时候给缺省值
int _month = 10;
int _day = 10;
Time _t;
int& _ref;
const int _n;
};
int main()
{
int i = 0;
Date d1(i);
d1.Print();//1 1 1
return 0;
} 友元
1. 友元提供了一种突破封装的方式,友元分为:友元函数和友元类。
2. 友元声明时,需要在友元函数大概友元类前面加friend,并且把友元声明放到对应的类的里面。
3. 友元函数可以访问类的私有和保护成员,但不是这个类的成员函数。
4. 友元函数可以在类定义的任何地方声明,不受类访问限定符限制。
5. 一个函数可以是多个类的友元函数。
6. 友元类中所有的成员函数都是另一个类的友元函数,都可以访问另一个类的私有成员和保护成员。
7. 友元关系是单向的、不能转达的。
//友元函数
#include <iostream>
using namespace std;
class B;//先声明一个B类类型,否则A中声明友元函数时,找不到B的类型。
class A
{
friend void func(const A& aa, const B& bb);// 友元声明
private:
int _a1 = 1;
int _a2 = 2;
};
class B
{
friend void func(const A& aa, const B& bb);// 友元声明
private:
int _b1 = 3;
int _b2 = 4;
};
void func(const A& aa, const B& bb)
{
cout << aa._a1 << endl;
cout << bb._b1 << endl;
}
int main()
{
A aa;
B bb;
func(aa, bb);
return 0;
}
//1
//3 //友元类
#include<iostream>
using namespace std;
class A
{
friend class B; // 友元声明
private:
int _a1 = 1;
int _a2 = 2;
};
class B
{
public:
void func1(const A& aa)
{
cout << aa._a1 << endl;
cout << _b1 << endl;
}
void func2(const A& aa)
{
cout << aa._a2 << endl;
cout << _b2 << endl;
}
private:
int _b1 = 3;
int _b2 = 4;
};
int main()
{
A aa;
B bb;
bb.func1(aa);
bb.func1(aa);
return 0;
}
//1
//3
//1
//3 内部类
1. 如果一个类定义在另一个类的内部,那么前面这个类就叫做内部类。
2. 内部类是一个独立的类,只是受外部类的类域限制和访问限定符限制。这意味着内部类虽然位于外部类的命名空间内,但并不依靠于外部类的实例,即外部类定义的对象中不包罗内部类。
3. 内部类默认是外部类的友元类,内部类可以访问外部类的成员。
3. 内部类本质也是一种封装,当A类跟B类紧密关联,A类的重要功能是为了服务于B类,那么可以考虑把A类设计为B类的内部类,如果将A类放置在B类的private、protected位置,那么A类就是B类的专属内部类,其他地方都用不了。
#include<iostream>
using namespace std;
class A
{
private:
static int _k;
int _h = 1;
public:
class B // B默认就是A的友元
{
public:
void foo(const A& a)
{
cout << _k << endl; //OK
cout << a._h << endl; //OK
}
};
};
int A::_k = 1;
int main()
{
cout << sizeof(A) << endl;//4
A::B b;
A aa;
b.foo(aa);//1 1
return 0;
} static修饰
1. 利用static修饰的成员变量,称为静态成员变量,静态成员变量必须要在类外初始化。
2. 静态成员变量为类的所有对象所共享,不属于某个详细的对象,存放在静态区。
3. 利用static修饰的成员函数,称为静态成员函数,静态成员函数没有this指针。
4. 可以在静态成员函数中访问静态成员变量,但是不能访问非静态的成员变量,因为静态成员函数没有this指针。
5. 可以在非静态的成员函数中访问恣意的静态成员变量和静态成员函数。
6. 突破类域就可以访问静态成员,可以通过 类名::静态成员 大概 对象.静态成员 的方式来访问静态成员变量和静态成员函数。
7. 静态成员也是类的成员,也受访问限定符的限制。
8. 静态成员变量不能在声明位置给缺省值初始化,因为静态成员变量不属于某个详细的对象,不走构造函数初始化列表。
#include<iostream>
using namespace std;
class A
{
public:
A()
{
++_scount;
}
A(const A& t)
{
++_scount;
}
~A()
{
--_scount;
}
static int GetACount()
{
return _scount;
}
private:
// 静态成员变量在类里面声明
static int _scount;
};
//静态成员变量在类外面初始化
int A::_scount = 0;
int main()
{
cout << A::GetACount() << endl;
A a1, a2;
A a3(a1);
cout << A::GetACount() << endl;
cout << a1.GetACount() << endl;
return 0;
}
//0
//3
//3 致谢
感谢您花时间阅读这篇文章!如果您对本文有任何疑问、建议或是想要分享您的看法,请不要夷由,在评论区留下您的宝贵意见。每一次互动都是我前进的动力,您的支持是我最大的鼓励。等待与您的交流,让我们共同发展,探索技术世界的无穷可能!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]