零规则与基类析构函数

rule of zero vs. base class destructors

本文关键字:析构函数 基类 规则      更新时间:2023-10-16

我有一个基类Base和一个派生类D,我想让编译器为我自动生成移动构造函数和移动赋值运算符。遵循零法则,我将所有内存管理留给编译器,只使用 2 级类(没有原始指针、数组等):

#include <iostream>
class Base{
  public:
    Base(): a_(42) {}
    virtual void show() { std::cout << "Base " << a_ << std::endl; }
  private:
    int a_;
};
class D : Base {
  public:
    D(): b_(666) {}
    void show() { std::cout << "D " << b_ << std::endl; }
  private:
    int b_;
};
int main() {
  Base b;
  b.show();
  D d;
  d.show();
  return 0;
}

应该就是这样吧?

输入C++核心准则:

基类析构函数应该是公共的和虚拟的,或者受保护的和非虚拟的。

啊,所以我想我将不得不添加一个析构函数来Base.但这会取消自动生成的移动功能!

这里的出路是什么?

您可以= default编译器希望生成

的所有内容。请参阅(底部):http://en.cppreference.com/w/cpp/language/rule_of_three

在您的情况下,它可能看起来像这样:

class Base{
  public:
    Base(): a_(42) {}
    Base(const Base&) = default;
    Base(Base&&) = default;
    Base& operator=(const Base&) = default;
    Base& operator=(Base&&) = default;
    virtual ~Base() = default;
    virtual void show() { std::cout << "Base " << a_ << std::endl; }
  private:
    int a_;
};

您可以创建一次类似的类

struct VirtualBase
{
      virtual ~VirtualBase() = default;
      VirtualBase() = default;
      VirtualBase(const VirtualBase&) = default;
      VirtualBase(VirtualBase&&) = default;
      VirtualBase& operator = (const VirtualBase&) = default;
      VirtualBase& operator = (VirtualBase&&) = default;
};

然后遵循零规则:

class Base : VirtualBase
{
public:
    Base(): a_(42) {}
    virtual void show() { std::cout << "Base " << a_ << std::endl; }
  private:
    int a_;
};