terms 4 :Make sure that objects are initialized before they're used
确定对象被使用前已经初始化
定义基本变量类型的同时对其进行赋值操作,创建一个对象时,在构造函数执行前进行初始化,也就是使用初始化列表进行初始化
总是在初始化列表中对所有成员变量赋值
初始化列表的初始化是真正的初始化,在构造函数函数体中对成员变量的赋值是一种伪初始化,初始化列表中的初始化次序最好和成员变量声明的次序相同,另外还要注意,某些变量的初始化次序有先后关系
不同编译单元内定义之non-local static 对象的初始化次序
一个常见的问题是类的包含问题,类A的成员变量中有一个类B的成员对象,类B的成员变量中也有一个类A的成员对象,这样,A的构造完成需要B构造完成,B的构造完成又需要A构造完成,因此会引发很大的错误,另一个问题是,不同的编译单元初始化次序问题,例如使用extern关键词时,被extern修饰的变量所在的编译单元应该首先被初始化,否则当前编译单元的编译就会获得一个未初始化的变量,从而引发错误,解决上述问题可以通过以函数调用替换直接使用对象,这设计到设计模式的知识,笔者理解不深。
terms 5 : Know what functions C++ silently writes and calls
了解C++默默编写并调用哪些函数
空类
当定义了一个空类,编译器会默认为类声明一个默认(default)构造函数、copy构造函数、默认析构函数、以及一个copy assignment操作符(以上函数均是public且inline的)。
编译器默认生成的函数存在的潜在问题
请看下面的代码实例
在明白下面的实例前,我们应该知道一些C++常识
引用的特点:
- 一个变量可取多个别名,也就是说一个变量可以有多个引用。
- 引用必须初始化,因此类中的reference成员变量应该像初始化const变量那样使用初始化列表进行初始化。
- 引用只能在初始化的时候引用一次 ,不能更改为转而引用其他变量。
#include <iostream>
using namespace std;
template<class T>
class NameObject{
public:
//一个自定义构造函数
NameObject(string &_name,const T&_year)
:name(_name),year(_year) //const成员变量通过初始化列表进行初始化
{
}
private:
string &name; //reference 引用
const T year; // const常量值
};
int main()
{
string newName("newName");
string oldName("oldName");
NameObject<int> name1(newName,23);
NameObject<int> name2(oldName,16);
// name1=name2;
cout << "Hello World!" << endl;
return 0;
}
上述事例中,由于只自定义了一个构造函数,编译器会默认为我们创建 copy构造函数、默认析构函数、以及一个copy assignment操作符,上述代码中析构函数以及copy构造函数的默认创建没有什么问题,但是由于reference成员变量的存在以及const成员变量的存在,此类的两个对象进行赋值时编译器会发生报错。原因就是引用不可更改,常量值也不能更改。
terms 6 : Explicitly disallow the use of compiler-generated functions you do not want
若不想使用编译器自动生成的函数,就该明确拒绝
紧接着terms5,当我们不希望类使用默认析构函数、以及一个copy assignment操作符时,我们应该明确禁止,那么如何禁止呢,编译器默认生成的函数是public访问属性,我们可以自己将默认析构函数、以及一个copy assignment操作符声明为private,这样,避免了编译器自动生成这些函数,但是这种方法不是绝对安全的,因为member(成员)函数和friend(友元)函数依旧可以访问并使用他们(虽然友元函数在实际的应用中也不推荐),然而我们可以只声明而不定义,这样在使用它们是会出现链接错误,也就是将编译期错误转移到连接期,但是越早发现错误越容易更改和解决错误,此时我们可以设置base class(基类)。
class Uncopyable{
protected:
Uncopyable(){} //允许构造和析构
~Uncopyable(){}
private:
Uncopyable(const Uncopyable&); //不允许copy 构造和 copy assignment
Uncopyable& operator =(const Uncopyable&);
};