C++:类和对象 III(初始化列表、explicit、友元、匿名对象)
目录
初始化列表
初始化列表的特点
类型转换、explicit
隐式类型转换
explicit关键字
static成员
静态成员变量
静态成员函数
友元
友元函数
友元类
内部类
匿名对象
编译器优化
初始化列表
初始化列表就是类成员初始化的地方
函数有它声明和定义的地方,变量也有,类成员也有
先来看看日期类的默认构造函数
class Date { public: Date(int year = 1900, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } private: int _year; int _month; int _day; }; int main() { Date d1(2024, 7, 15); return 0; }
在类里面显示出来的成员我们把它叫做声明
如果你认为我们就这样把_year,_month,_day给初始化了,那就错了
这并不是初始化,这是赋值
如果我们要初始化类成员的话应该这样做
class Date { public: Date(int year = 1900, int month = 1, int day = 1) :_year(year) ,_month(month) ,_day(day) {} private: int _year; int _month; int _day; };
这一块就是初始化列表
先是一个冒号开始,然后以逗号分隔,成员变量后面跟初始值或者表达式
这样我们就完成了一个成员的定义和初始化
那么这两种写法有什么区别呢?
这两种写法给我们带来的效果都是一样的,但是无论怎么写我们的成员变量都要经过初始化列表一遍,就算没有写初始化列表也会!所以这里建议尽量使用初始化列表初始化
如果我们不知道初始化列表怎么给,我们可以在声明的地方给一个缺省值,例如:
class Date { public: Date(int year = 1900, int month = 1, int day = 1) :_year(year) ,_month(month) ,_day(day) {} private: int _year = 1900; int _month = 1; int _day = 1; };
这样就算我们没有写初始化列表也会给我们自动初始化上这些值
注意:
const成员变量,带引用的成员变量,只有一次初始化的机会!那就是在初始化列表中!
class A { public: A(int a = 1) { _a = a; } private: const int _a; };
因为const常量不能被赋值,只能在初始化的地方被初始化,正确代码如下:
class A { public: A(int a = 1) :_a(a) {} private: const int _a; };
class A { public: A(int a = 1) :_a(a) {} private: int& _a; };
初始化列表的特点
如果我们没有在声明的地方给缺省值,也没有写初始化列表,那么值由编译器决定
如果我们给了缺省值没有写初始化列表,那么会根据缺省值初始化
如果我们即给了缺省值也给了初始化列表,那么根据初始化列表的值初始化
注:上述行为于构造函数内部行为无关
初始化列表中按照成员在类中声明的定义来初始化,于初始化列表中出现的先后顺序无关
例如:
class A { public: A() :_a(1) , _b(_a) {} //private: int _b; int _a; }; int main() { A a; cout
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。