0

Let me explain the somewhat confusing title.

The question is about abstract base classes and pure virtual method (implementations). I understand so far that:

  • A class is abstract if it contains at least one pure virtual method (which can have an implementation in Base). One often makes the constructor of such a class protected.
  • A Child : Base class must implement all pure virtual methods to become instantiatable.

I was trying to build an abstract base class that, by design of its methods and pure virtual methods, defines a certain process (which will never change in its basic routine), parts of which will change depending on the child class implementations. I was hoping to realize a design somewhat like the follwing:

class Base {
protected:
    Base() {
        setup();
    }
    virtual ~Base() {}
    void setup() {
        //do stuff that will always be the same
        setupDetails();
    }
    virtual void setupDetails() = 0;
    void mainProcess() {
        //do stuff that will always be the same
        processDetails();
    }
    void processDetails() = 0;
};
inline void Base::setupDetails() {} //(**)
inline void Base::processDetails() {}


class Child : public Base {
private:
    Child() : Base() {}
    virtual ~Child() {}
    void setupDetails() {//do child stuff}
    void processDetails() {//do child stuff}
};

In my concrete case of application, Base is some "Quiz" class which provides a gui and a mechanism to ask questions in certain time intervals etc. The Child classes provide the actual questions/answers etc.

The provided design (at least to my naive mind) would force child classes to implement certain process steps which is otherwise not subject to change. However, this concept does not work, because "pure virtual functions are being called" in Base.

  • I would have to do it the other way around: Having the child classes build the process by using the base class methods (which I don't want!)
  • Or make the base class non-abstract by not marking the xxxDetails() methods pure, but simply virtual.

However: Although it seems logical that Base can't call a Childs methods, I still wonder... Base knows that an instantiatable Child MUST implement its pure virtual functions! And Base will only ever be instantiated when there is such a Child which means that there indeed IS an implementation. What's the problem? And how can I get the design I want? (*)

Or does the problem only arise because there is such a pure virtual method call in the constructor of Base, because the "first child" might as well be abstract itself?

(*) Maybe there is a big flaw in my whole notion of this problem, please enlighten me, then...

(**) These empty implementations prevent the "pure method call" error (?) but of course the parent methods are called, not the ones of the child.

LCsa
  • 607
  • 9
  • 30
  • 1
    There's nothing wrong with a base class calling functions which it's declared as pure virtual. Are you concerned specifically about doing so from the base class constructor? (see https://stackoverflow.com/questions/962132/calling-virtual-functions-inside-constructors) – Sneftel Mar 15 '19 at 12:07
  • @Sneftel I got an error without the pure virtual parent implementation. And it didn't call the child's implementation when I provided a parent implementation. While typing it came to my mind that maybe the problem was the fact that the parent's constructor called a pure virtual method... What I want to achieve is that the pure virtual child method implementations are called from within the parent's methods as in the sample code... – LCsa Mar 15 '19 at 12:11
  • Yeah, it sounds like you need to read the linked question. The rules are different while the constructor (or destructor) is running. – Sneftel Mar 15 '19 at 12:13
  • @Sneftel Thanks for the link! That supports my notion about the problem being the method call in the constructor of `Base`! So my concept is fine as long as I eliminate all pure virtual method calls in the parent's constructor... calling `Base::setup()` from within the child's constructor should be feasible for and okay when within the responsibility of any user of my class, haha! :D – LCsa Mar 15 '19 at 12:13
  • While I understand that the problem was already covered in the linked question, I don't think it's a duplicate. I was not specifically asking about calling pure virtual functions in constructors, but merely the fact that I did turned out to be the solution to my problem/concept. – LCsa Mar 15 '19 at 12:20
  • Yeah, SO's idea of a "duplicate question" is a little broad. In general, we mark things as "duplicates" where the answers to an existing question fit this one, not just where the question is the same. Which is to say, it's not a blame thing -- I think it's reasonable that you posted this question, rather than magically finding that other one -- but an organization thing, so that future visitors asking questions like yours can be guided to the answer. – Sneftel Mar 15 '19 at 12:46
  • @Sneftel I do understand. Still, I think a brief answer along the lines of: "There is nothing wrong with this concept at all. The problem originates from calling a pure virtual method in the Base`s constructor as discussed in this question ." Would be appropriate... If you agree, feel free to post it and I'll gladly accept your answer. :-) By the way, in the meantime I adjusted the design and introduced a setup() method that is to be called by the child class and it works like a charm! – LCsa Mar 15 '19 at 13:28

0 Answers0