纯虚拟析构函数足以使类抽象吗?

时间:2018-08-23 08:56:41

标签: c++11 interface abstract-class

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

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

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),所以我现在或全部都不会打招呼:大家好!

3 个答案:

答案 0 :(得分: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;
}

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

答案 1 :(得分:0)

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

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

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

inline IBase::~IBase() {}

答案 2 :(得分:0)

  

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

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

IBase::~IBase() {}

某处。 GotW 31是该主题的不错阅读。

  

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

否。