Skip to content

C++11 defalut & delete

问题

编译器会在特定条件下自动生成这五种特殊成员函数:

  1. 默认构造函数:只有当类中没有声明任何构造函数时才会生成
  2. 析构函数:几乎总是会自动生成
  3. 拷贝构造函数:如果没有定义移动操作,则会自动生成;
  4. 拷贝赋值运算符:如果没有定义移动操作,则会自动生成;
  5. 移动构造函数:只有当类没有定义拷贝操作、移动操作和析构函数时才会自动生成
  6. 移动赋值运算符:只有当类没有定义拷贝操作、移动操作和析构函数时才会自动生成
cpp
#include <iostream>
class A
{
};

int main()
{
    A a;               // 如果编译通过,就是编译器自动生成了默认构造
    A b = a;           // 如果编译通过,就是编译器自动生成了拷贝构造
    b = a;             // 如果编译通过,就是编译器自动生成了拷贝赋值
    A c(std::move(a)); // 如果编译通过,就是编译器自动生成了移动构造
    b = std::move(c);  // 如果编译通过,就是编译器自动生成了移动赋值
    return 0;
}

delete & default

  • = default关键字让编译器生成默认实现
    • 当您声明了其他构造函数,但仍然想要默认构造函数时
    • 当您想要确保某个特殊成员函数被生成,即使按规则它不会被自动生成
    • 当您想要显式表明您的意图,增强代码可读性
  • = delete关键字禁用特定函数
    • 防止对象被复制(禁用拷贝构造和拷贝赋值)
    • 限制对象创建方式(禁用默认构造函数)
    • 防止不希望的类型转换(禁用特定参数类型的构造函数)
cpp
#ifndef TEST_H
#define TEST_H

#include <iostream>
class Test
{
public:
    explicit Test(std::string &str);
    explicit Test() = default;                // 生成默认无参构造
    Test &operator=(const Test &t) = default; // 生成默认拷贝赋值运算符
    ~Test() = default;                        // 生成默认析构函数
    Test(const Test &&) = delete;    // 禁用移动构造

    // 为了方便打印,我这里把属性设为公有
public:
    std::string s;
};

#endif // TEST_H

注意

  1. 含有引用属性(在构造函数初始化)的类需要自定义构造函数和拷贝操作,默认生成的是不行的(调用时出错)
  2. 为了安全性、性能等因素,不使用时我们应该禁用其他构造和拷贝操作,比如单例类