Is it dangerous to create pure virtual function of a virtual function?
Asked Answered
C

2

11

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.

Callisthenics answered 31/3, 2017 at 14:55 Comment(6)
It's a fair enough question, but not for StackOverflow, which doesn't deal with programming style issues. If you have a base method defined, one has to wonder what has happened to make it invalid in an intermediate class.Yean
It's perfectly possible and achieves what you want. Nothing dangerous about it. Whether or not it's a good style is very subjective.Katanga
gcc 4.9 signals an error on instanciation of SuperDerived (provided Derived is MyBase) if someMethod is commented out / not defined in SuperDerived, as @JesperJuhl explainsWrand
Did you intend for MyBase to use private inheritance from NonEditableSuperBase?Bidden
I would make virtual in NonEditableSuperBase protectedBlight
@AdrianMcCarthy If my filling about your intent is right and you don't already know about it, you could be interested to declare someMethod pure virtual in the "super base", but still provides a definition of it outside the class (a pure virtual function can have a definition). If my intent was to provide some generic code reusable by derivates, but still force derivates to override it, I would do this way.Andean
V
11

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.

Vercingetorix answered 31/3, 2017 at 16:13 Comment(0)
B
2

[I'm assuming that the intent was for MyBase to publicly derive from NonEditableSuperBase, which is not what the code sample in the question actually does.]

It doesn't seem inherently dangerous, but consider that a class like SuperDerived that derives from MyBase could explicitly choose to use the NonEditableSuperBase implementation.

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

This satisfies the pure-virtual requirement imposed by MyBase but acts exactly as if MyBase didn't have that requirement. You've made the author of SuperDerived do something, but you haven't actually prevented them from using the ultimate base class's implementation.

Bidden answered 31/3, 2017 at 16:16 Comment(2)
Firstly, yes, I wanted to publicly derive from NonEditableSuperBase, I have corrected the code, thank you. Secondly, I wasn't intending to prevent the users from using the NonEditableSuperBase methods, just remind them that they have to implement them (if they do what you have shown they know what they are doing)Callisthenics
Check out this other question about having a pure-virtual method that has an implementation in the base class. This achieves the same effect: providing reasonable default behavior while requiring implementors of derived classes make a conscious choice to get the default behavior. #2089583Bidden

© 2022 - 2024 — McMap. All rights reserved.