Convert to Polymorphism?

I

Immortal Nephi

Each derived classes are derived from class A through virtual
multiple inheritance. Only class E is defined. Each data members and
member functions are inherited into class E from one base class and
all derived classes.
Each derived classes have the same Run() member function name, but
different implementation. The variable of pFunc_E is a pointer to Run
() member function. It does not have pointer to member function array
because I want to reassign any Run() member function to pFunc_E at run-
time execution.
pFunc_E is like dispatch function. Inheritance is the answer to
divide from one large base class into derived sub-classes (from one
large source code to multiple source code for better readability).
Class E is used to communicate to all sub-classes.
Please tell me if one object with multiple sub-classes good design.
If not, can it be converted to polymorphism? Run() can be set to pure
virtual function in class A and (non-pure) virtual functions to all
derived sub-classes. What is your advice? Please give me your
example if you can. Thanks…

class E;

class A
{
public:
A();
~A();
void Run_A();
void (E::*pFunc_E)();
void Test();
};

class B1 : virtual public A
{
public:
B1();
~B1();
void Run_B1();
};

class B2 : virtual public A
{
public:
B2();
~B2();
void Run_B2();
};

class B3 : virtual public A
{
public:
B3();
~B3();
void Run_B3();
};

class B4 : virtual public A
{
public:
B4();
~B4();
void Run_B4();
};

class C1 : virtual public B1, virtual public B2, virtual public B3,
virtual public B4
{
public:
C1();
~C1();
void Run_C1();
};

class C2 : virtual public B1, virtual public B2, virtual public B3,
virtual public B4
{
public:
C2();
~C2();
void Run_C2();
};

class C3 : virtual public B1, virtual public B2, virtual public B3,
virtual public B4
{
public:
C3();
~C3();
void Run_C3();
};

class D1 : virtual public C1, virtual public C2, virtual public C3
{
public:
D1();
~D1();
void Run_D1();
};

class D2 : virtual public C1, virtual public C2, virtual public C3
{
public:
D2();
~D2();
void Run_D2();
};

class E : virtual public D1, virtual public D2
{
public:
E();
~E();
void Run_E();
};

A::A() {}
A::~A() {}
void A::Run_A() {}
void A::Test() {}

B1::B1() {}
B1::~B1() {}
void B1::Run_B1() { pFunc_E = &B2::Run_B2; }

B2::B2() {}
B2::~B2() {}
void B2::Run_B2() { pFunc_E = &B3::Run_B3; }

B3::B3() {}
B3::~B3() {}
void B3::Run_B3() { pFunc_E = &B4::Run_B4; }

B4::B4() {}
B4::~B4() {}
void B4::Run_B4() { pFunc_E = &C1::Run_C1; }

C1::C1() {}
C1::~C1() {}
void C1::Run_C1() { pFunc_E = &C2::Run_C2; }

C2::C2() {}
C2::~C2() {}
void C2::Run_C2() { pFunc_E = &C3::Run_C3; }

C3::C3() {}
C3::~C3() {}
void C3::Run_C3() { pFunc_E = &D1::Run_D1; }

D1::D1() {}
D1::~D1() {}
void D1::Run_D1() { pFunc_E = &D2::Run_D2; }

D2::D2() {}
D2::~D2() {}
void D2::Run_D2() { pFunc_E = &B1::Run_B1; }

E::E() {}
E::~E() {}
void E::Run_E() {}

int main()
{
E e[3];

e[0].pFunc_E = &B1::Run_B1;
e[1].pFunc_E = &B1::Run_B1;
e[2].pFunc_E = &B1::Run_B1;

for (int y = 0; y < 3; y++)
{
for (int x = 0; x < 10; x++)
(e[y].*(e[y].pFunc_E))();
}

system("pause");

return 0;
}
 
S

Salt_Peter

Each derived classes are derived from class A through virtual
multiple inheritance. Only class E is defined. Each data members and
member functions are inherited into class E from one base class and
all derived classes.

Thats a misconception. your derived class (E) is not selectively
inheriting members and functions from its base class(es). What it does
inherit is their accessible interfaces.

Otherwise, an instance of class E -is- an instance of the base class
(es), through and through. Think of an egg where the yellow yolk is
the base class portion of the object.

Instead of inherit, think transposition.
Each derived classes have the same Run() member function name, but
different implementation. The variable of pFunc_E is a pointer to Run
() member function. It does not have pointer to member function array
because I want to reassign any Run() member function to pFunc_E at run-
time execution.
pFunc_E is like dispatch function. Inheritance is the answer to
divide from one large base class into derived sub-classes (from one
large source code to multiple source code for better readability).
Class E is used to communicate to all sub-classes.
Please tell me if one object with multiple sub-classes good design.
If not, can it be converted to polymorphism? Run() can be set to pure
virtual function in class A and (non-pure) virtual functions to all
derived sub-classes. What is your advice? Please give me your
example if you can. Thanks…

google for NVI (non-virtual idiom)

You should read the faq on diamond inheritance as well.
http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.8
class E;

class A
{
public:
A();
~A();
void Run_A();
void (E::*pFunc_E)();
void Test();

};

class B1 : virtual public A
{
public:
B1();
~B1();
void Run_B1();

};

class B2 : virtual public A
{
public:
B2();
~B2();
void Run_B2();

};

class B3 : virtual public A
{
public:
B3();
~B3();
void Run_B3();

};

class B4 : virtual public A
{
public:
B4();
~B4();
void Run_B4();

};

class C1 : virtual public B1, virtual public B2, virtual public B3,
virtual public B4
{
public:
C1();
~C1();
void Run_C1();

};

class C2 : virtual public B1, virtual public B2, virtual public B3,
virtual public B4
{
public:
C2();
~C2();
void Run_C2();

};

class C3 : virtual public B1, virtual public B2, virtual public B3,
virtual public B4
{
public:
C3();
~C3();
void Run_C3();

};

class D1 : virtual public C1, virtual public C2, virtual public C3
{
public:
D1();
~D1();
void Run_D1();

};

class D2 : virtual public C1, virtual public C2, virtual public C3
{
public:
D2();
~D2();
void Run_D2();

};

class E : virtual public D1, virtual public D2
{
public:
E();
~E();
void Run_E();

};

A::A() {}
A::~A() {}
void A::Run_A() {}
void A::Test() {}

B1::B1() {}
B1::~B1() {}
void B1::Run_B1() { pFunc_E = &B2::Run_B2; }

B2::B2() {}
B2::~B2() {}
void B2::Run_B2() { pFunc_E = &B3::Run_B3; }

B3::B3() {}
B3::~B3() {}
void B3::Run_B3() { pFunc_E = &B4::Run_B4; }

B4::B4() {}
B4::~B4() {}
void B4::Run_B4() { pFunc_E = &C1::Run_C1; }

C1::C1() {}
C1::~C1() {}
void C1::Run_C1() { pFunc_E = &C2::Run_C2; }

C2::C2() {}
C2::~C2() {}
void C2::Run_C2() { pFunc_E = &C3::Run_C3; }

C3::C3() {}
C3::~C3() {}
void C3::Run_C3() { pFunc_E = &D1::Run_D1; }

D1::D1() {}
D1::~D1() {}
void D1::Run_D1() { pFunc_E = &D2::Run_D2; }

D2::D2() {}
D2::~D2() {}
void D2::Run_D2() { pFunc_E = &B1::Run_B1; }

E::E() {}
E::~E() {}
void E::Run_E() {}

int main()
{
E e[3];

e[0].pFunc_E = &B1::Run_B1;
e[1].pFunc_E = &B1::Run_B1;
e[2].pFunc_E = &B1::Run_B1;

for (int y = 0; y < 3; y++)
{
for (int x = 0; x < 10; x++)
(e[y].*(e[y].pFunc_E))();
}

system("pause");

return 0;

}

Complicated designs, specially multiple diamond inheritance meshes
will fail. Simplicity is beautifull. Stick to the basics, in this
case, note the base constructor A() invoked in the derived class's
init list ( C() : A() { ... } // invoke A() ).

#include <iostream>

class A
{
public:
A() { std::cout << "A()\n"; }
virtual ~A() { std::cout << "~A()\n"; }
protected:
virtual void VirtualRun()
{
std::cout << "A::VirtualRun()\n";
}
public:
void Run() { A::VirtualRun(); }
void PolyRun() { VirtualRun(); }
};

class B1 : public virtual A
{
protected:
void VirtualRun() { std::cout << "B1::VirtualRun()\n"; }
public:
void Run() { B1::VirtualRun(); }
};

class B2 : public virtual A
{
protected:
void VirtualRun() { std::cout << "B2::VirtualRun()\n"; }
public:
void Run() { B2::VirtualRun(); }
};

class C : public B1, public B2
{
public:
C() : A() { std::cout << "C()\n"; } // invoke A()
~C() { std::cout << "~C()\n"; }
protected:
void VirtualRun() { std::cout << "C::VirtualRun()\n"; }
public:
void Run() { VirtualRun(); }
void Run_A() { A::Run(); }
void Run_B1() { B1::Run(); }
void Run_B2() { B2::Run(); }
void Run_all()
{
A::Run();
B1::Run();
B2::Run();
Run();
}
};

int main()
{
C c;
c.Run_all();

A* const p_a = &c;
p_a->Run(); // calls A::VirtualRun()

// calls most derived VirtualRun()
// whatever that might be
p_a->PolyRun();

}

/*
A()
C()
A::VirtualRun()
B1::VirtualRun()
B2::VirtualRun()
C::VirtualRun()
A::VirtualRun() // p_a->Run()
C::VirtualRun() // p_a->PolyRun()
~C()
~A()
*/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top