16

考虑以下程序:

#include <string>

struct S {
    S (){}

private:
    void *ptr = nullptr;
    std::string str = "";
};

int main(){}

-Weffc++在 GCC 4.7.1 上编译时会输出:

警告:“结构 S”具有指针数据成员 [-Weffc++]
警告:但不覆盖 'S(const S&)' [-Weffc++]
警告:或 'operator=(const S&)' [-Weffc++]

这通常没问题,除了这个例子中的几件事:

  1. 如果我注释掉任何构造函数、指针声明或字符串声明,警告就会消失。这很奇怪,因为您认为仅指针就足够了,但事实并非如此。此外,将字符串声明更改为整数声明也会导致它消失,因此它仅在存在字符串(或可能其他选择类)时出现。为什么在这种情况下警告会消失?

  2. 当所有指针都指向现有变量(通常由操作系统维护)时,通常会出现此警告。没有new,也没有delete。在这些情况下,当复制带有句柄的类时,我不想要深拷贝。我希望两个句柄都指向同一个内部对象(例如窗口)。有没有办法让编译器实现这一点,而无需不必要地重载复制构造函数和赋值运算符,或者完全禁用警告#pragma?当三法则甚至不适用时,为什么我首先会受到困扰?

4

2 回答 2

26

GCC-Weffc++有几个问题,我从不使用它。检查“问题”的代码非常简单,因此警告最终过于生硬和无用。

该特定警告基于Effective C++第一版的第 11 项,Scott 在以后的版本中对其进行了更改(为了更好)。G++ 代码不检查实际的动态分配,只检查指针成员的存在。

在比较第一版和第三版的指南时,请参阅我在GCC 的 bugzilla中写的关于此警告的内容:

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

替换为第 14 条:“仔细考虑在资源管理类中复制行为”——该建议不太具体,但更有用。我不知道如何把它变成一个警告!

于 2012-07-17T19:17:24.097 回答
5
  1. 当你这样做时,你就有了一个 POD 结构。因为它不能有任何构造函数,-Weffc++所以不用检查。

  2. 使用引用或shared_ptr对象或包装指针的任何其他对象。

于 2012-07-16T02:47:37.970 回答