10-2 显式默认和显式删除

10.2 显式默认和显式删除

​ 如果在类中添加了自定义的构造函数,其原本所属于的默认构造函数就会被破坏,失去其平凡性。因此提供了显式默认的方式来保证默认的构造函数仍然能被生成。

10.2.1 默认自带的构造函数

  • 默认构造函数

  • 析构函数

  • 复制构造函数

  • 复制赋值运算符函数

  • 移动构造函数

  • 移动赋值运算符函数

10.2.2 显式默认的应用场景

​ 在下面的代码中,如果添加了default,则原来的类成为了平凡类。

class Trivial
{
int i;

public:
Trivial(int n) : i(n), j(n) {}
Trivial() = default;
int j;
};

int main(int argc, char const *argv[])
{
Trivial v, v2;
v2 = v; //复制默认构造函数
return 0;
}

10.2.3 显式删除的应用场景

1. 删除基类函数代替与私有它

​ 在下面这种情况下,如果使用注释的方法,则会报错。

class Base
{
// void foo(long &);
public:
void foo(long &) = delete;
void foo(int) {}
};

class Derived : public Base
{
public:
using Base::foo;
void foo(const char *) {}
};

int main()
{
Derived d;
d.foo("hello");
d.foo(5);
}
2. 删除new函数来防止在堆上创建对象

​ 在下面的情况中,删除了new就不能在堆上创建对象。

struct type
{
void* operator new(size_t) = delete;
}

type global_var;
int main()
{
static type static_var;
type auto_var;
type* var_ptr = new type; //失败
}
3. 删除析构函数来只允许动态创建对象
struct type
{
~type() = delete;
}

type global_var; //失败
int main()
{
static type static_var; //失败
type auto_var; //失败
type* var_ptr = new type; //成功
}