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.
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.