"= default"析构函数和空析构函数之间有什么区别?

del*_*rst 29 c++ destructor private class c++11

我想阻止我的类的用户将它用作自动变量,所以我编写如下代码:

class A {
private:
  ~A() = default;
};

int main() {
  A a;
}
Run Code Online (Sandbox Code Playgroud)

我希望代码不会被编译,但是g ++编译它没有错误.

但是,当我将代码更改为:

class A {
private:
  ~A(){}
};

int main() {
  A a;
}
Run Code Online (Sandbox Code Playgroud)

现在,g ++给出了~A()私有的错误,这是我的期望.

"= default"析构函数和空析构函数之间有什么区别?

How*_*ant 25

你的第一个例子不应该编译.这表示编译器中的编译错误.此错误已在gcc 4.9及更高版本中修复.

在这种情况下,定义的析构函数= default微不足道的.这可以通过检测到std::is_trivially_destructible<A>::value.

更新

C++ 11(和C++ 14)声明如果有一个用户声明的析构函数(并且如果你没有用户声明的移动特殊成员),则隐式生成复制构造函数和复制赋值运算符仍然会发生,但该行为已被弃用.这意味着如果您依赖它,您的编译器可能会给您一个弃用警告(或者可能不会).

都:

~A() = default;
Run Code Online (Sandbox Code Playgroud)

和:

~A() {};
Run Code Online (Sandbox Code Playgroud)

用户声明的,因此它们在这一点上没有区别.如果您使用这些表单中的任何一个(并且不声明移动成员),则应显式默认,显式删除或显式提供复制成员,以避免依赖于已弃用的行为.

如果您确实声明了移动成员(有或没有声明析构函数),则隐式删除复制成员.

  • @delphifirst:编译器错误现在非常普遍.当我还是一名学生时,在20世纪80年代早期,我们了解到,任何不良行为都是我们代码中的错误,而不是编译器中的错误.今天我经常让编译器崩溃(ICE,内部编译器错误),然后毫无疑问它是谁的错... (2认同)