目录
构造函数
为类提供了构造函数后,程序员就必须为它提供默认构造函数。
定义默认构造函数的方式有两种:
- 给已有构造函数的所有参数化提供默认值
- 通过函数重载来定义另一个构造函数
在构造函数中使用new的注意事项
- 如果在构造函数中使用new来初始化指针成员,则应在析构函数中使用delete
- New和delete必须相兼容。New对应于delete,new[]对应于delete[]
- 如果有多个构造函数,则必须以相同的方式使用new,要么都带中括号,要么都不带。因为只有一个析构函数,所有的构造函数都必须与它兼容。
- 应定义一个复制构造函数,通过深度复制将一个对象初始化为另一个对象。
- 应当定义一个赋值运算符,通过深度复制将一个对象复制给另一个对象
访问权限:派生类不能直接访问基类的私有成员,而必须通过基类方法进行访问。创建派生类时,程序首先创建基类对象。
派生类构造函数的要点:
- 首先创建基类对象
- 派生类构造函数应通过成员初始化列表将基类信息传递给基类构造函数
- 派生类构造函数应初始化派生类新增的数据成员
析构函数
析构函数完成清理工作。释放对象的顺序与创建对象的顺序相反,即首先执行派生类的析构函数,然后自动调用基类的析构函数。对于基类,即使它不需要析构函数,也应提供一个虚析构函数。
复制构造函数
将一个对象复制到新创建的对象中,新建一个对象并将其初始化为同类现有对象时,复制构造函数都将被调用。以下4中声明都将调用复制构造函数:
- String a(b); //调用string(const string &)
- String a = b; //调用string(const string &)
- String a = string(b); //调用string(const string &)
- String*a = new string(b); //调用string(const string &)
当函数按值传递对象或者函数返回对象时,都将使用复制构造函数。
默认的复制构造函数逐个复制非静态成员(成员复制也称浅复制),复制的是成员的值。
在下述情况下,将使用复制构造函数:
- 将新对象初始化为一个同类对象
- 按值将对象传递给函数
- 函数按值返回对象
- 编译器生成临时对象
移动构造函数
通过提供一个使用左值引用的构造函数和一个使用右值引用的构造函数,将初始化分成了两组。使用左值对象初始化对象时,将使用复制构造函数,而使用右值对象初始化对象时,将使用移动构造函数。移动构造函数的原型如下:
Useless::Useless(Useless && f);
将左值转化为右值引用,使用static_cast<Useless &&>,使用std::move(Useless)
注意事项
- 关键字delete可用于禁止编译器使用特定方法。要禁止复制,可将复制构造函数和赋值运算符放在类定义的private部分。
- 提供了移动构造函数,因此编译器不会自动创建默认的构造函数、复制构造函数和复制赋值构造函数。