构造函数
1、构造函数的与类的名字相同,并且不能指定返回类型,不能声明为const。因为构造函数的工作是初始化对象,不管对象是否为const,都用一个构造函数来初始化该对象。
2、构造函数分两个阶段执行:(1)初始化阶段;(2)普通的计算阶段。
3、使用构造函数初始化列表的版本初始化数据成员,没有定义初始化列表的构造函数版本在构造函数函数体中对数据成员赋值。
4、没有默认构造函数的类类型的成员,以及const或引用类型的成员,不管是哪种类型,都必须在构造函数初始化列表中进行初始化。
5、成员初始化的次序就是定义成员的次序。按照与成员声明一致的次序编写构造函数初始化列表是个好习惯。
6、可以通过将构造函数声明为explicit,来防止在需要隐式转换的上下文中使用构造函数。
默认构造函数
1、包括:(1)无显式定义,编译器自动生成一个无参的公有的构造函数(合成的默认构造函数)。(2)显式定义一个没有任何形参或所有形参都有默认值的构造函数。
2、如果类中显式定义了一个构造函数,则系统不会自动生成默认构造函数。
3、一个类最多只能有一个默认构造函数,也可以没有默认构造函数。实际上,如果定义了其他构造函数,则提供一个默认构造函数几乎总是对的。
复制构造函数
1、什么时候调用
*根据另一个同类型的对象显式或隐式初始化一个对象
*调用函数时,用值传递方式,把对象为实参,传给形参
*从函数返回时复制一个对象
*初始化顺序容器中的元素
*根据容器初始化式列表初始化数组元素。
2、对于类类型对象,初始化的复制形式(=)和直接形式()有所不同:直接初始化直接调用与实参匹配的构造函数,复制初始化总是调用复制构造函数。
3、对于不支持复制的类型,不能对这些类型的对象使用复制初始化。
4、何时需要定义自己的复制构造函数?
*一个类的数据成员中含有指针,或者有成员表示在函数中分配的其他资源
*另一些类在创建新对象时必须做一些特定的工作
5、通过声明(但不定义)private复制构造函数,可以禁止任何复制类类型对象的尝试。
赋值操作函数
1、赋值操作函数是一个成员函数,返回值是赋值语句的左值对象的引用,返回语句一般是return *this;左值是当前对象,右值是实参。
2、每个类都有一个赋值操作函数,若无显式定义,编译器会自动生成(公有),复制每个非静态数据成员。
3、类中有指针数据成员,且在构造函数执行中用new动态申请内存,在对象被撤销时要用delete来回收内存,就要显式定义复制构造函数和赋值操作函数。(防止指针成员的值,导致同一内存多次被释放)
析构函数
1、何时调用析构函数?撤销对象前由系统自动调用,回收该对象的储存空间,对象生命周期结束。
2、调用情况:
*局部对象、全局对象和静态对象的撤销。析构顺序与构造顺序相反,容器中的元素总是按逆序撤销。合成的析构函数按创建时的逆序撤销每个非static成员。
*用delete运算符回收先前用new创建的对象
*临时匿名对象使用完毕。
3、析构函数通常用于释放在构造函数或在对象生命期内获取的资源。
4、分配了资源的类一般需要定义析构函数以释放那些资源。
5、即使我们编写了自己的析构函数,合成析构函数仍然运行。
6、如果类需要析构函数,则它也需要赋值操作函数和复制构造函数。