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

时间:2014-10-08 09:35:59

标签: c++ c++11

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

  

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

     

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

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

1 个答案:

答案 0 :(得分:5)

这个bug report提到了这个在gcc中没有发出警告的测试用例:

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

int main() {
 W w {};
 W v = w;
}

请参阅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;

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

  

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

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

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

  •   
     

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