提问人:chris 提问时间:7/16/2012 最后编辑:Robᵩchris 更新时间:11/23/2022 访问量:24295
了解 -Weffc++
Understanding -Weffc++
问:
请考虑以下程序:
#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
答:
当你这样做时,你就有一个 POD 结构。因为它不能有任何构造函数,所以不费心检查。
-Weffc++
使用引用或对象或包装指针的任何其他对象。
shared_ptr
评论
void *
HWND hwnd = CreateWindow (...); ShowWindow (hwnd, SW_SHOW);
HWND
CreateWindow
DestroyWindow
DestroyWindow
-Weffect
void *
DestroyWindow
shared_ptr<HWND>
HWND *
shared_ptr<void>
GCC有几个问题,我从不使用它。检查“问题”的代码非常简单,因此警告最终过于生硬和无用。-Weffc++
该特定警告基于有效C++第一版的第11项,Scott在以后的版本中对其进行了更改(为了更好)。G++ 代码不检查实际的动态分配,只检查指针成员是否存在。
在比较第一版和第三版的指南时,请参阅我在 GCC 的 bugzilla 中写的关于此警告的内容:
第 11 项:定义 copy 构造函数和 assignment 运算符的类 动态分配的内存。
替换为第 14 项:“仔细考虑复制行为 资源管理类“ - 建议不那么具体,但更有用。我是 不知道如何把它变成警告!
评论
老问题,但“这通常没有问题”并不完全正确:
-Weffc++ 强制代码反映该行为。这里说的是,如果您按原样使用代码,则隐式复制运算符只会在与原始结构相同的地址上创建“ptr”点。
也许这就是你想要的原因,但它只是警告你,因为这是一种隐含的行为。对于正在编写代码的您来说,这可能很清楚,但对于其他开发人员来说,这很清楚吗?
要摆脱此警告,您应该做的是显式删除 copy 和 = 运算符或定义它们。要删除复制构造函数,您可以执行以下操作:
S(const S&) = delete;
上一个:什么是三分法则?
下一个:了解 -Weffc++
评论