如果存在用户定义的析构函数,如何禁用隐式定义的复制构造函数生成

Mir*_*pas 6 c++ c++11

是否有任何编译器标志来强制执行下一个规则?

如果T具有用户定义的析构函数或用户定义的复制赋值运算符,则不推荐生成隐式定义的复制构造函数.

如果T具有用户声明的析构函数或用户声明的复制构造函数,则不推荐生成隐式定义的复制赋值运算符(因为C++ 11).

我有兴趣在Clang,Visual Studio 2013或GCC中的任何一个中强制执行规则,因为代码库将与所有这些规则一起编译.

小智 5

错误报告提到此测试用例,它不会在gcc中发出警告:

struct W {
  int a;
  ~W() { a = 9; }
};

int main() {
 W w {};
 W v = w;
}
Run Code Online (Sandbox Code Playgroud)

请参阅Johnathan Wakely的评论:

这不是真的,编译器可以(并且确实)警告法律代码.

我确认了这一点,我们希望在某些时候发出警告,这将使我们能够改进这部分-Weffc++警告:

*第11项:为具有动态分配内存的类定义复制构造函数和赋值运算符.

( 更多细节见PR 16166)

也许我们可以调用此警告-Wdeprecated-special-members,并启用它-Weffc++,在C++ 11中也可以-Wdeprecated

Clang已经警告过这个-Wdeprecated:

main.cpp:3:3: warning: definition of implicit copy constructor for 'W' is deprecated because it has a user-declared destructor [-Wdeprecated]

  ~W() { a = 9; }

  ^

main.cpp:8:8: note: implicit copy constructor for 'W' first required here

 W v = w;
Run Code Online (Sandbox Code Playgroud)

Microsoft明确声明Visual Studio在这种情况下不会发出警告:

此外,C++ 11标准指定了以下附加规则:

  • 如果显式声明了复制构造函数或析构函数,则不建议自动生成复制赋值运算符.

  • 如果显式声明了复制赋值运算符或析构函数,则不建议自动生成复制构造函数.

在这两种情况下,Visual Studio都会继续隐式自动生成必要的函数,并且不会发出警告.