再探析构函数

再探析构函数

调用析构函数时机

无论何时一个对象被销毁,就会自动调用其析构函数:

  • 变量在离开其作用域时被销毁
  • 当一个对象被销毁时,其成员被销毁
  • 容器(无论是标准库容器还是数组)被销毁时,其元素被销毁。
  • 对于动态分配的对象,当对指向它的指针应用delete运算符时被销毁
  • 对于临时对象,当创建它的完整表达式结束时被销毁

使用=default

C++11新标准中,如果我们需要默认的行为,那么可以通过在参数列表后面写上=default来要求编译器生成构造函数。

class Sales_data{
public:
    Sales_data() = default;
    Sales_data(const Sales_data&) = default;
    Sales_data& operator = (const Sales_data &);
    ~Sales_data() = default;
};

Sales_data& Sales_data::operator=(const Sales_data&) = default;

(ps:感觉没啥用。。)

使用=delete

大多类应该定义默认构造函数、拷贝构造函数和拷贝赋值运算符,无论是隐式地还是显式地,但对于某些类来说,这些操作没有合理的意义。在此情况下,定义类时必须采用某种机制阻止拷贝或赋值。

例如,iostream类阻止了拷贝,以避免多个对象写入或读取相同的IO缓冲。

使用=delete定义删除的函数

struct NoCopy{
    NoCopy() = default; //使用合成的默认构造函数
    NoCopy(const NoCopy&) = delete; //阻止拷贝
    NoCopy &operator=(const NoCopy&) = delete; //阻止赋值
    ~NoCopy() = default;
};

析构函数不能是删除的成员

对于一个删除了析构函数的类型,编译器将不允许定义该类型的变量或创建该的临时对象。(这里同理Singleton单例模式中的将析构函数私有化,如果将析构函数私有化后,将不允许在栈上创建类对象,但可以动态分配这种类型的对象)虽然不能定义这种类型的变量或成员,但可以动态分配这种类型的对象。但是不能释放这些对象。

#include <iostream>

using namespace std;

struct NoDtor{
    NoDtor() = default;
    ~NoDtor() = delete;
};

int main()
{
    //NoDtor nd; //erorr,NoDtor的析构函数delete
    NoDtor *p = new NoDtor(); 
    //delete p; //error,NoDtor的析构函数delete
    return 0;
}

合成的拷贝控制成员可能是删除的

如果一个类的数据成员不能默认构造、拷贝、复制或销毁,则对应的成员函数将被定义为删除的。同时如上所说,如果一个成员有删除的或不可访问的析构函数会导致合成的默认和拷贝构造函数被定义为删除的,其原因是如果没有这条规则,我们可能会创建出无法销毁的对象。


参考:《C++ Primer》第五版

猜你喜欢

转载自www.cnblogs.com/Mered1th/p/10920500.html