首页 > 解决方案 > 带有指针的 C++ -Weffc++ 警告

问题描述

我很难理解这个错误。我正在用-Weffc++标志编译。

这个结构编译得很好。

struct A
{
A(){}
int * first = nullptr;
int second = 0;
};

这不是编译。

struct B
{
B(){}
int * first = nullptr;
std::vector<int> second{};
};

我正进入(状态:

prog.cc:14:8: warning: 'struct B' has pointer data members [-Weffc++]
   14 | struct B
      |        ^
prog.cc:14:8: warning:   but does not override 'B(const B&)' [-Weffc++]
prog.cc:14:8: warning:   or 'operator=(const B&)' [-Weffc++]

但这又可以正常编译了。

struct C
{
int * first;
std::vector<int>& second;
};

为什么我们会收到关于指针的错误(它们在每个结构中)?为什么添加std::vector<int>调用错误?我用最新的gcc 9.00C++2a

标签: c++compiler-errorscompilationgcc-warning

解决方案


这是一个警告,而不是错误。在拥有默认构造函数时,您有一些不倾向于正确使用的指针。如果您希望警告消失,请定义构造函数和赋值运算符。三/五/零法则

struct B {
    int* first;
    std::vector<int> second;

    B() : first(nullptr), second{} {}  // default
    B(const B&) = delete;              // copy ctor
    B(B&&) = delete;                   // move ctor
    B& operator=(const B&) = delete;   // copy assignment
    B& operator=(B&&) = delete;        // move assignment  
    ~B() { delete[] first; }           // dtor
};

如果不这样做,移动和复制类的实例可能会导致默认实例化构造函数/赋值运算符产生不良影响,例如复制/移动无法复制/移动的资源。看看析构函数,想想如果让默认方法处理指针会发生什么。


推荐阅读