[c++11]显式默认和删除函数

参考:

Special member functions

Explicitly Defaulted and Deleted Functions

特定成员函数

编译器会自动生成以下特定成员函数:

  1. 默认构造器
  2. 复制构造器
  3. 复制赋值运算符
  4. 析构器

c++11开始,将移动构造器移动赋值运算符也指定了特定成员函数

在实际操作过程中,遵循以下规则:

  • 如果任何构造器被显式声明了,那么不会自动生成默认构造器
  • 如果声明了虚拟析构器,那么不会自动生成默认析构器
  • 如果移动构造器或者移动赋值运算符被声明了,那么
    • 不会自动生成复制构造器
    • 不会自动生成复制赋值运算符
  • 如果声明了复制构造器、复制赋值运算符、移动构造器、移动赋值运算符和析构器,那么
    • 不会自动生成移动构造器
    • 不会自动生成移动赋值运算符

c++11开始,还遵循以下规则:

  • 如果复制构造器或析构器被显式声明了,那么不会自动生成复制赋值运算符
  • 如果复制赋值运算符或析构器被显式声明了,那么不会自动生成复制构造器

=default和=delete

c++11之前,声明对象不可复制,必须显式在私有域内声明复制构造器和复制赋值运算符

struct noncopyable
{
  noncopyable() {};

private:
  noncopyable(const noncopyable&);
  noncopyable& operator=(const noncopyable&);
};

而由于复制构造器的声明,编译器不会再自动生成默认构造器,必须显式声明

而使用默认和删除函数,直接指定即可,修改如下:

struct noncopyable
{
  noncopyable() =default;
  noncopyable(const noncopyable&) =delete;
  noncopyable& operator=(const noncopyable&) =delete;
};

将复制构造器和复制赋值运算符删除,同时保留了默认构造器

使用这种方式还可以实现对象不可移动的定义

struct nonmoveable
{
  nonmoveable() =default;
  nonmoveable(nonmoveable&) =delete;
  nonmoveable& operator=(nonmoveable&&) =delete;
};

删除函数进一步使用

=delete可以进一步作用于普通的成员函数和运算符

# 删除new运算符
void* operator new(std::size_t) = delete;
# 避免调用浮点数
void call_with_true_double_only(float) =delete;
void call_with_true_double_only(double param) { return; }
# 通过删除模板函数,仅能调用双精度
template < typename T >
void call_with_true_double_only(T) =delete; //prevent call through type promotion of any T to double from succeeding.
void call_with_true_double_only(double param) { return; } // also define for const double, double&, etc. as needed.