Search code examples
c++abstract-classpure-virtual

Is it dangerous to create pure virtual function of a virtual function?


Let us suppose that we have an abstract class NonEditableSuperBase from which we create another abstract class MyBase.

The first class NonEditableSuperBase has a virtual function (non pure virtual). However, I want to force that if someone creates a class that derives from MyBase, he/she must provide an implementation to the mentioned function.

Hence, my idea is to define the function as pure virtual in MyBase.

My question: Is it a bad idea given that it was just virtual in NonEditableSuperBase?

Example:

//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
};

Update: As an example, in my case I want to create some derived classes from the QAbstractTableModel class of the Qt framework. To reuse some code I want to create an intermediate abstract class.

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

However, I want to ensure that the models (MyModelA, MyModelB) re-implement some of the virtual functions of QAbstractTableModel (like the ::index() function) because some of the additional methods of MyAbstractModel requires specific implementations of the primer functions.


Solution

  • From ISO IEC 14882 2014:

    § 10.4 says:

    5 [ Note: An abstract class can be derived from a class that is not abstract, and a pure virtual function may override a virtual function which is not pure. —end note ]

    So It's perfectly possible to do that.

    Example of use case:

    You can have a basic type, that is implemented as a concrete type (base class). Now, for subtypes, we might be in a need of further additional information. So, we can have an abstract intermediate object to meet our needs.