在 derived class 中定义析构函数需要复制赋值运算符

Defining destructor in derived class requires copy assignment operator

看看这个代码示例:

class A {
    A(const A&) = delete;
    A &operator=(const A&) = delete;    
protected:
    A() { }
    virtual ~A() { } // required for inheritance
    A(A&&) = default;
    A &operator=(A&&) = default;
};

struct B : public A {
    ~B() { } // Without the destructor the code compiles
};

int main(void)
{
    B b = B();
}

此代码无法编译,g++-9 告诉我(简而言之)

line 15: error: use of deleted function 'B::B(const B&)'
line 9: note: 'B::B(const B&)' is implicitly deleted because the default definition would be ill-formed:
line 9: error: use of deleted function 'A::A(A&)'

有关完整的错误消息,请参阅 godbolt

为什么编译器不使用 class A 中的移动 constructor/move 赋值运算符?如果我删除 struct B 中定义的析构函数,代码就会编译。这种行为的原因是什么?

当你

~B() { }

B中你阻止了编译器生成移动构造函数,所以它只有一个复制构造函数。由于 A 不可接受,因此无法编译。

当您删除它时,编译器可以自动创建移动构造函数,您就可以开始了。


请注意,这仅适用于 C++17 之前的版本。使用 C++17 的有保证的复制省略,B b = B(); 变为 B b();(如果它实际上可以编译)所以不会发生复制或移动。