Base and Derived class constructor polymorphism woes

Sorry for the vague title.

I'm writing a set of classes, and im having trouble thinking of an intuitive way of breaking up what is done in the base constructor and what is done in the derived constructor.

My problem is as follows:

All classes require steps A, C, and E to be completed in sequence. Therefore it made sense to put them in the base constructor.

Steps B and D are unique to each of the derived classes.

Unfortunately, B must be completed after A and before C, and similarily D must be completed after C and before E. These are OpenGL function calls and I am contrained to the ordering of them.

I originally tried something along the lines of this, hoping to encapsulate as much as possible in the base class:

public class MyBase
{
    MyBase()
    {
        A():
        B();
        C();
        D();
        E();  
    }
    void A() {...}
    void C() {...}
    void E() {...}
    virtual void B() = 0;
    virtual void D() = 0;
}

public class MyDerived : public MyBase
{
    MyDerived() : MyBase() {}
    void B() {...}
    void D() {...}
}

But that is not possible in C++...

Is there a more intuitive way of doing this other than:

public class MyBase
{
    MyBase() {}
    void A() {...}
    void B() {...}
    void C() {...}
}

public class MyDerived : public MyBase
{
    MyDerived()
    {
        A():
        B();
        C();
        D();
        E();  
    }
    void B() {...}
    void D() {...}
}

I am hoping to avoid as much code repetition as possible.

Any ideas?

2 Answers
  1. If you definitely want to call it in the constructor, and are not ok with calling it after, you can reduce the clutter a little bit by doing the below.

    public class MyBase
    {
        protected:
        void templateMethod()
        {
            A():
            B();
            C();
            D();
            E();  
        }
        private:
        void A() {...}
        void C() {...}
        void E() {...}
        virtual void B() = 0;
        virtual void D() = 0;
    };
    
    public class MyDerived : public MyBase
    {
        MyDerived() : MyBase() {templateMethod();}
        void B() {...}
        void D() {...}
    };
    

    This is not quite a true template method pattern though, since now all the derived classes have to call it, instead of it being called once for the base class.

    2013-02-20 02:02:27
  2. Given that calling virtual function in constructor can be dangerous, is using macro an acceptable solution for you?

    #define MY_BASE_INIT A();B();C();D();E();
    
    public class MyBase
    {
        MyBase() {}
        void A() {...}
        void C() {...}
        void E() {...}
    }
    
    public class MyDerived : public MyBase
    {
        MyDerived()
        {
            MY_BASE_INIT
        }
        void B() {...}
        void D() {...}
    }
    
    2013-02-20 02:53:16
Related Articles
You Might Also Like