【问题标题】:Does a pure virtual destructor suffice to make a class abstract?纯虚析构函数是否足以使类抽象?
【发布时间】:2018-08-23 08:56:40
【问题描述】:

我希望这不会成为“重复”,因为关于(纯)虚拟解构有很多问题(是的,我确实知道)。

我想用一堆方法构建一个“接口”(-> 抽象类),可以重新实现,但不需要。所以我喜欢:

class IBase
{
public:
  virtual bool doThis() { return true; }
  virtual bool doThat() { return true; }
}

我给出了一堆实现,有些使用doThis,有些使用doThat。这就是为什么“接口”方法只是虚拟的而不是纯粹的。喜欢:

class Derived1 : public IBase
{
public:
  bool doThis() override { return doSomething(); }
}

class Derived2 : public IBase
{
public:
  bool doThat() override { return doSomethingElse(); }
}

问题:这个IBase 类是可实例化的,它一定不能实例化,因为它什么都不做......

我的问题:定义一个纯虚拟析构函数virtual ~IBase() = 0 使其无法实例化就足够了吗? 和/或我是否需要删除标准构造函数IBase() = delete

也许我最终因为想了太久而变成了代码盲,所以我会提前原谅。

编辑:我最初的问候被删了(由我或 SO),所以我现在或永远不会向你们打招呼:嘿伙计们!

【问题讨论】:

  • “它不能”这是一个完全任意的要求。 “因为它什么都不做”数字零、空集、恒等函数在某种意义上都“什么都不做”,但我们仍然保留它们。

标签: c++11 interface abstract-class


【解决方案1】:

就我个人而言,我会避免将析构函数设为纯虚拟函数。 在 C++ 中,您可以定义一个已声明为虚拟的函数。请参阅以下示例:

class IBase
{
public:
IBase() = default;
virtual ~IBase() = default;

virtual bool doThis() = 0;

virtual bool doThat() = 0;
};

bool IBase::doThis()
{
    return true;
}

bool IBase::doThat()
{
    return true;
}

class Derived2 : public IBase
{
public:
bool doThat() override { return false; }

bool doThis() override { return IBase::doThis(); } // call parent implementation
};

int main()
{
    Derived2 a;
    std::cout << a.doThat() << std::endl;
    std::cout << a.doThis() << std::endl;
}

但是,从设计的角度来看,从接口派生的类应该实现其所有方法。因此,如果可以的话,我建议您重新考虑您的解决方案。

【讨论】:

    【解决方案2】:

    定义一个纯虚析构函数virtual ~IBase() = 0 使其不可实例化就足够了吗?

    是的。必须注意,纯虚析构函数与非特殊纯虚函数的定义不同:对于析构函数,必须有定义。因此,您必须添加

    IBase::~IBase() {}
    

    某处。关于这个主题的好读物是GotW 31

    和/或我是否需要删除标准构造函数IBase() = delete

    没有。

    【讨论】:

      【解决方案3】:

      是的,使析构函数纯粹就足以使类抽象。抽象类定义为“至少有一个纯虚成员函数”。

      但是,请注意,您仍然需要为纯虚拟析构函数提供实现,否则派生类将无法调用它。你可以这样做:

      class IBase
      {
      public:
        virtual ~IBase() = 0;
        virtual bool doThis() { return true; }
        virtual bool doThat() { return true; }
      }
      
      inline IBase::~IBase() {}
      

      【讨论】:

        猜你喜欢
        • 2019-04-20
        • 1970-01-01
        • 2011-03-21
        • 2019-12-08
        • 2011-03-31
        • 1970-01-01
        • 2020-06-19
        • 1970-01-01
        • 2013-01-15
        相关资源
        最近更新 更多