c++关键字 =delete和=default

在C++的类中,有四类特殊的成员函数① 默认构造函数;② 拷贝构造函数;③ 拷贝赋值函数(operator=);④ 析构函数;它们控制着类的实例的创建、初始化、拷贝以及销毁。

(1)默认构造函数:如果对构造函数进行了重载,则编译器不会隐式的生成一个默认的构造函数,此时如果调用了默认构造函数会在编译时报错,为了避免这种情况,一般会选择重写默认构造函数,且函数体为空。关键字 =default 优化了这种行为,用该关键字标记重写的默认拷贝构造函数,编译器会隐式生成一个版本,在代码更加简洁的同时,编译器隐式生成的版本的执行效率更高

class Mine 
{
public:
    // 重载构造函数,此时不会隐式生成默认构造函数 
    Mine(int num) {}
    
    // 可选择重写默认构造函数 
    Mine() {}
    
    // 关键字 =default 标记编译器隐式生成该类的默认构造函数,
    // 代码更简洁,且隐式生成的版本执行效率更高 
    Mine() = default;
};

int main()
{
    // 调用默认构造函数 
    Mine ob; 
    // 调用默认拷贝构造函数 
    Mine pOb(ob);  
    
    // 需要特别注意的是:因为tOb是在创建时被赋值的,
    // 所以此处的赋值操作符调用的是默认拷贝构造函数 
    Mine tOb = pOb;
    
    Mine sOb;
    // 在构造完成之后,赋值操作符执行的就是赋值运算了,
    // 所以此时调用的就是拷贝赋值函数 
    sOb = tOb;
    
    /** 离开作用域时自动调用默认的析构函数  */
    return 0;
}

(2)拷贝构造函数 和 拷贝赋值函数:不论有没有对它们进行重载,编译器始终会隐式生成默认版本,但有的时候不希望类实例进行拷贝构造或拷贝赋值,此时可以重写它们并将权限设置为private,但这样只是利用语法特性来碰巧实现效果,且对友元会带来困惑。可以使用关键字 =delete 标记不想被类实例调用的拷贝构造和拷贝赋值,相当于删除了它们

class Mine
{
public:
    // 保证重载了构造函数后,编译器会隐式生成一个默认版本 
    Mine() = default;
    Mine(Mine& ob) = delete;
    Mine& operator=(Mine& ob) = delete;
};

int main()
{
    Mine ob
    
    // 编译错误,调用的拷贝构造函数已删除 
    Mine pOb(ob);
    // 编译错误,调用的拷贝构造函数已删除 
    Mine tOb = pOb;
    
    Mine sOb;
    // 编译错误,调用的拷贝赋值函数已删除 
    sOb = tOb;
    
    return 0;
}

(3)析构函数:一个类中有且仅有一个析构函数(所以=delete不能用于析构函数),它是一个无参无返回值不能被重载的特殊成员函数,由系统自动调用,析构函数如果被重写,则系统会调用重写的版本,否则调用隐式生成的默认版本:

class Mine
{
public:
    ~Mine() {} // 显示定义,相当于重写,若没有,则调用编译器默认生成的版本 
    ~Mine(int) {} // 编译错误,析构函数不允许被重载 
    ~Mine() = delete; // 编译错误,类仅有一个析构函数,删除了析构怎么销毁对象 
};

你可能感兴趣的:(c++)