条款04 确定对象被使用前先已被初始化
减小不确定性,在使用对象之前先将它初始化。对于无成员的内置类型,手动完成这件事情。
int x = 0;
const char * text = "A style";
double d;
std::cin >> d;
对于其他类型,初始化责任在于构造函数。
事实上,在构造函数内部赋值并不是成员变量的初始化过程,成员变量的初始化过程发生在默认构造函数内部,这个过程成员变量的值可能不是我们所想要的。解决该问题的办法是采用初始化列表,该初始化列表位于默认构造函数或者构造函数。例如构造函数的初始化列表:
ABEntry::ABEntry(const std::string& name, cosnt std::string& address, const std::list<PhoneNumber>& phones):theName(name), theAddress(address), thePhones(phones), numTimesConsulted(0)
{
}
如果是位于默认构造函数,参数为空就可,类会调用各自的默认构造函数,内置类型需要自己初始化。如下
ABEntry::ABEntry():theName(), theAddress(), thePhones(), numTimesConsulted(0)
{
}
总而言之,使用初始化列表,不会带来不确定性,非常必要,并且比复制更急高校。
成员初始化顺序
- class的成员变量顺序是个声明顺序相同,和初始化列表中出现的顺序无关(所以需要格外的注意各个成员的次序有关联关系的变量,比如数组和大小)
- 基类先与派生类初始化
总结 - 为内置型对象进行手工初始化
- 构造函数最好采用初始化列表
条款05 了解C++默认编写并调用了哪些函数
对于一个类,编译器会暗自为class默认构造函数(不带参数)、拷贝构造函数、析构函数、以及等号重载运算符。
条款06 若不想使用编译器自动生成的函数,就该明确拒绝
如果你想要防止对象的拷贝构造和=运算,有两种做法
- 类自身调整
- 将拷贝构造函数和=重载声明为Private,但是不去定义他们。这样可以方式对象调用私有成员,同时,member和friend调用他们也会产生链接错误
- 声明一个base class,让该类继承于base class。
- 基类的拷贝构造函数和=声明为private,同时没有定义。这样派生类调用基类的拷贝构造函数和=就会调用基类的拷贝构造函数和=重载云运算符。
条款07为多态基类声明virtual析构函数
- 带多态性质base class应该声明一个virtual析构函数。如果class带有任何virtual函数,他就应该拥有一个virtual析构函数
- 如果一个基类指针指向派生类,基类析构函数声明为virtual,删除这个指针,会删除整个对象,不会产生内存泄漏。
- classes的设计目的如果不是作为base class使用,或不是为了具备多态性,就不该声明virtual析构函数
条款08别让异常逃离析构函数
条款09 绝不在构造和析构调用virtual函数
- 基类的构造函数在派生类构造函数之前被调用,这个过程对象的类型是base-class 而不是derived-class
条款10 令operator=返回一个reference to *this
- 为了更好了处理连续赋值
条款11 在operator=中处理“自我赋值”
- 函数内部加上证同测试(identity test)
if(this == &rhs)//rhs是参数
- 在删除一个对象之前,先保存一下对象的副本,如果删除出现异常,可还原现场。
参考链接
static关键字

本文探讨了C++中对象初始化的策略,包括使用初始化列表来减少不确定性,理解构造函数与成员变量初始化的顺序,以及如何正确处理自我赋值。强调了在构造函数中采用初始化列表的重要性,避免在构造和析构过程中调用虚函数,以及在多态基类中声明虚析构函数的必要性。
23万+

被折叠的 条评论
为什么被折叠?



