理解-Weffc ++

chr*_*ris 14 c++ pointers g++ compiler-warnings rule-of-three

考虑以下程序:

#include <string>

struct S {
    S (){}

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

int main(){}
Run Code Online (Sandbox Code Playgroud)

在使用-Weffc++GCC 4.7.1 编译时,这将吐出:

warning: 'struct S' has pointer data members [-Weffc++]
warning:   but does not override 'S(const S&)' [-Weffc++]
warning:   or 'operator=(const S&)' [-Weffc++]

这通常没问题,除了这个例子的几个东西:

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

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

Jon*_*ely 22

海湾合作委员会-Weffc++有几个问题,我从来没有使用它.检查"问题"的代码非常简单,因此警告最终变得过于生硬和无益.

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

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

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

替换为第14项:"仔细考虑复制资源管理类中的行为" - 建议不太具体,但更有用.我不知道怎么把它变成警告!

  • -Weffc ++的另一个问题:不允许在*private*基类上使用非虚拟析构函数,这是没有充分理由的. (3认同)

Arp*_*ius 5

  1. 当你这样做时,你有一个POD结构.因为它不能有任何构造函数,-Weffc++所以不打扰检查.

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