【问题标题】:How to disable implicitly-defined copy constructor generation when there is user defined destructor当有用户定义的析构函数时如何禁用隐式定义的复制构造函数生成
【发布时间】:2014-12-02 22:07:13
【问题描述】:

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

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

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

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

【问题讨论】:

  • 你可以继承noncopyable:boost.org/doc/libs/1_55_0/libs/utility/…
  • 对于 VS 你可以激活“warning-as-errors”
  • @MarcoA。是警告吗?在哪个版本中,处于什么警告级别?
  • @EdChum 我想让对象可复制,但有时可能会忘记添加赋值运算符/复制构造函数
  • 我不确定这是一个警告,但应该是。如果是,你肯定可以打开它

标签: c++ c++11


【解决方案1】:

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 都会继续自动生成 隐含必要的函数,并且不会发出警告。

【讨论】:

  • -Wdeprecated 对我来说已经足够好了。我已经有错误警告:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-21
  • 2012-02-28
  • 2013-03-13
  • 2011-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多