考虑以下计划:
#include <string>
struct S {
S (){}
private:
void *ptr = nullptr;
std::string str = "";
};
int main(){}
当在GCC 4.7.1上使用-Weffc++
进行编译时,这将吐出:
warning: 'struct S' has pointer data members [-Weffc++] warning: but does not override 'S(const S&)' [-Weffc++] warning: or 'operator=(const S&)' [-Weffc++]
通常没问题,除了这个例子的几件事:
如果我注释掉任何构造函数,指针声明或字符串声明,警告就会消失。这很奇怪,因为你认为指针就足够了,但事实并非如此。此外,将字符串声明更改为整数声明也会导致它消失,因此只有在有字符串(或可能是其他选择类)时才会出现。为什么在这种情况下警告会消失?
当所有指针都在指向现有变量(通常由操作系统维护)时,通常会出现此警告。没有new
,也没有delete
。当复制带有句柄的类时,我不想要深层复制。我希望两个句柄指向同一个内部对象(例如窗口)。有没有办法让编译器实现这一点而不会不必要地重载复制构造函数和赋值运算符,或者使用#pragma
完全禁用警告?当三法则甚至不适用时,为什么我首先被困扰?
答案 0 :(得分:21)
海湾合作委员会的-Weffc++
有几个问题,我从不使用它。检查“问题”的代码非常简单,因此警告最终变得过于直率和无益。
该特定警告基于第一版 Effective C ++ 的第11项,Scott在后续版本中对其进行了更改(为更好)。 G ++代码不检查实际的动态分配,只检查指针成员的存在。
在比较第一版和第三版的指南时,查看我在GCC's bugzilla中撰写的有关此警告的内容:
第11项:为类定义复制构造函数和赋值运算符 动态分配内存。
替换为第14项:“仔细考虑复制行为 资源管理类“ - 建议不太具体,但更有用。我是 不知道怎么把它变成警告!
答案 1 :(得分:5)
当你这样做时,你有一个POD结构。因为它不能有任何构造函数,-Weffc++
不会打扰检查。
使用引用或shared_ptr
对象或包装指针的任何其他对象。