On Feb 22, 3:20*pm, "Alf P. Steinbach" <al...@start.no> wrote:
> * Immortal Nephi:
>
> > I want to show you my example like polymorphism. *Three
> > subclasses as Center share data member of base class as Top.
>
> OK.
>
> > *I do not
> > have to use static data member. *It may look like multiple diamond.
>
> Yes, it is a diamond inheritance pattern.
>
> > Only Bottom sub-class is able to access three subclasses as Center. *I
> > wonder why member functions can't access between Center1 subglass and
> > Center2 subclass so it has to go through Bottom subclass.
>
> It's unclear what you mean.
>
>
>
>
>
> > class Top
> > {
> > public:
> > * *Top() : integer(0) { cout << "Top()" << endl; }
> > * *~Top() { cout << "~Top()" << endl; }
>
> > * *void Run() { cout << "Top::Run()" << endl; }
>
> > protected:
> > * *int integer;
> > };
>
> > class Center1 : virtual public Top
> > {
> > public:
> > * *Center1() { cout << "Center1()" << endl; }
> > * *~Center1() { cout << "~Center1()" << endl; }
>
> > * *void Run() { integer += 0x1; cout << "Center1::Run() = " << hex <<
> > integer << endl; }
> > };
>
> > class Center2 : virtual public Top
> > {
> > public:
> > * *Center2() { cout << "Center2()" << endl; }
> > * *~Center2() { cout << "~Center2()" << endl; }
>
> > * *void Run() { integer += 0x20; cout << "Center2::Run() = " << hex <<
> > integer << endl; }
> > };
>
> > class Center3 : virtual public Top
> > {
> > public:
> > * *Center3() { cout << "Center3()" << endl; }
> > * *~Center3() { cout << "~Center3()" << endl; }
>
> > * *void Run() { integer += 0x400; cout << "Center2::Run() = " << hex <<
> > integer << endl; }
> > };
>
> > class Bottom : public Center1, public Center2, public Center3
> > {
> > public:
> > * *Bottom() { cout << "Bottom()" << endl; }
> > * *~Bottom() { cout << "~Bottom()" << endl; }
>
> > // void Run() { cout << "Bottom::Run()" << endl; Center1::Run();
> > Center2::Run(); Center3::Run(); }
> > * *void (Bottom::*pRun[3])();
> > };
>
> > int main(void)
> > {
> > * *Bottom b;
>
> > * *b.pRun[0] = &Center1::Run;
> > * *b.pRun[1] = &Center2::Run;
> > * *b.pRun[2] = &Center3::Run;
>
> This is very dangerous because correct operation of a Bottom instance here
> depends on the client code doing correct external initialization. Instead you
> should do such initialization in the class' constructor. And if the ability to
> change the assignments is desired, provide also that via safe methods.
>
> > * *(b.*(b.pRun[0]))();
> > * *(b.*(b.pRun[1]))();
> > * *(b.*(b.pRun[2]))();
>
> This is like having a good working car at hand and instead of driving it as it's
> meant to (see below), delving into the engine and trying to make the car go
> forward by hand-cranking the starter motor, trying all kinds of ingenious
> reconnections of the starter motor wires in order to get rid of that
> inexplicable resistance...
>
> > * *b.~Bottom();
>
> Don't invoke destructors explicitly. It's also done automatically. And at that
> point (at the 'return' below) you have Undefined Behavior; you'd have to
> terminate the program right here in order to avoid the UB.
>
>
>
>
>
> > * *return 0;
> > }
>
> > Output to Screen
> > Top()
> > Center1()
> > Center2()
> > Center3()
> > Bottom()
> > Center1::Run() = 1
> > Center2::Run() = 21
> > Center3::Run() = 421
> > ~Bottom()
> > ~Center3()
> > ~Center2()
> > ~Center1()
> > ~Top()
>
> Try
>
> * * *int main()
> * * *{
> * * * * Bottom b;
>
> * * * * *b.Center1::Run();
> * * * * *b.Center2::Run();
> * * * * *b.Center3::Run();
> * * *}
>
> >> By the way, which book are you using that doesn't discuss this?
>
> >> It can be helpful to others to know about that book, to avoid it.
>
> > Yes, I am novice to OOP, but I have great knowledge of procedural
> > programming of C. *I do self-study for personal use. *I use C++
> > Practice book.
>
> Uhm, author? I can't find it on Amazon, nor in ACCU reviews.
Alf,
Here is the book called Practical C++. The brand name is QUE. ISBN:
0-7897-2144--9.
|