1. 编译器默认添加的函数

自写类的时候,如果没有显式的写出来构造函数、析构函数、拷贝构造函数、拷贝赋值函数。如果程序中这些函数被需要(被调用),编译器就会默认的创建这些函数。

默认的构造函数和析构函数都是空实现的。

默认的拷贝构造函数和拷贝赋值函数都是浅拷贝。


如果有自己写的一个或者多个构造函数(不管有无参数),那么编译器都不会再添加默认的构造函数。

2. 如何禁止拷贝构造函数、拷贝赋值函数?

可以将拷贝构造函数、拷贝赋值函数显式的定义为private。这样可以,但是并不是绝对的安全,因为此时,类的成员函数、友元类、友元函数,依然可以调用这些函数。

比较好的做法是,将函数声明private的,同时不对该函数进行定义

此后,如果直接调用这两个函数,会在编译期报错。如果用友元或者成员函数调用,会在连接期报错。


也可以单独写一个unCopyable类,然后base 私有继承unCopyable,base内不用再声明拷贝构造和拷贝赋值,这样的操作,会将错误从连接时期提前至编译时期。

3. virtual 修饰的析构函数

一个子类对象经由一个父类指针delete时,如果父类的析构函数不是虚函数,那么执行delete后,该子类对象是“部分销毁”的,子类对象内部继承自父类的资源都会被释放掉,但是子类自己独有的资源可能会造成泄漏

一个原则是:如果类中没有虚函数,表明该类不想被继承,那么析构函数也不需要弄成虚函数;如果一个类中有至少一个虚函数,表明该类有可能被继承,那么析构函数最好弄成虚函数。

4. 纯虚函数与纯虚析构函数的区别

一个类,一旦内部有一个纯虚函数,那么该类就是一个抽象类,无法实例化。只能等待被继承。

纯虚函数与纯虚析构函数的区别在于纯虚函数不需要提供定义,而纯虚析构函数需要具体定义。原因在于:当发生多态时,通过父类指针delete子类对象时,先执行子类的析构函数,再调用父类的析构函数,从下至上逐层析构,那么抽象类的纯虚析构函数,如果没有具体实现,在连接时,就会报错,所以必须要有具体实现。保证继承体系的完整析构过程。