创建虚拟函数的纯虚函数是危险的吗?

时间:2017-03-31 14:55:39

标签: c++ abstract-class pure-virtual

让我们假设我们有一个抽象类NonEditableSuperBase,我们从中创建另一个抽象类MyBase

第一个班级NonEditableSuperBase有一个虚拟功能(非纯虚拟)。但是,我想强制说,如果有人创建了一个派生自MyBase的类,他/她必须为上述函数提供实现。

因此,我的想法是在MyBase中将函数定义为纯虚拟。

我的问题:这是一个坏主意,因为它只是NonEditableSuperBase中的虚拟内容?

示例:

//NonEditableSuperBase.h
class NonEditableSuperBase
{
  ...
  public:
    virtual int someMethod(); //It has an implementation, suppose {return 42;}
};

//MyBase.h
class MyBase: public NonEditableSuperBase
{
  public:
     explicit MyBase();       
     virtual ~MyBase() = default;       
     virtual int someMethod() = 0;  //I make it pure virtual
};

//MyBase.cpp
MyBase::MyBase() : NonEditableSuperBase() { }

//Now someone creates a derived class from MyBase.
class SuperDerived : public MyBase
{
  public:
    explicit SuperDerived();
    int someMethod(); //The user must create an implementation of the function
};

更新: 作为一个例子,在我的例子中,我想从Qt框架的QAbstractTableModel类创建一些派生类。要重用一些代码,我想创建一个中间抽象类。

QAbstractTableModel <- MyAbstractModel <- MyModelA (or MyModelB ... etc).

但是,我想确保模型(MyModelA,MyModelB)重新实现QAbstractTableModel的一些虚函数(如:: index()函数),因为MyAbstractModel的一些额外方法需要特定的实现引物功能。

2 个答案:

答案 0 :(得分:11)

来自ISO IEC 14882 2014

  

§10.4说:

     

5 [注意:抽象类可以从非抽象的类派生,纯虚函数可以   覆盖不纯的虚函数。 - 后注]

所以完全可以这样做。

用例示例:

您可以拥有一个基本类型,它是作为具体类型(基类)实现的。现在,对于子类型,我们可能需要进一步的附加信息。因此,我们可以有一个抽象的中间对象来满足我们的需求。

答案 1 :(得分:2)

[我假设MyBase的目的是公开派生自NonEditableSuperBase,这不是问题中的代码示例实际上做的。]

它本身并不危险,但考虑到源自MyBase的SuperDerived类可以明确选择使用NonEditableSuperBase实现。

class SuperDerived : public MyBase {
  public:
    using NonEditableSuperBase::someMethod;
    // Or, explicitly:
    // int someMethod() override { return NonEditableSuperBase::someMethod(); }
};

这满足了MyBase强加的纯虚拟要求,但就像MyBase没有那个要求一样。您已经让SuperDerived的作者做了某事,但实际上并没有阻止他们使用最终基类的实现。