Problems with constructor polymorphism for Base and Derived
Sorry for the vague title.
I am writing a bunch of classes and they have a hard time thinking of an intuitive way to break up what is done in the base constructor and what is done in the derived constructor.
My problem is this:
All classes require steps A, C, and E in sequence. So it makes sense to put them in the base constructor.
Steps B and D are unique to each derived class.
Unfortunately, B must terminate after A and before C, and similarly D should terminate after C and before E. These are OpenGL function calls and I cannot order them.
I initially tried something like this, hoping to encapsulate as much as possible in a 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 this is not possible in C ++ ...
Is there a more intuitive way to do 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 hope to avoid as much code repetition as possible.
Any ideas?
If you definitely want to call it in the constructor and cannot call it, you can reduce the clutter a bit by doing 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 really a true template template because now all derived classes must call it instead of being called once for the base class.
Considering that calling a virtual function in a constructor can be dangerous, is using a 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() {...}
}