* Immortal Nephi:
The name _B is invalid (it's reserved for the implementation) because it starts
with an underscore followed by uppercase.
First of all, as a novice *don't* use
- goto
- member pointers
- all uppercase names for non-macro things
- macro names that are not all uppercase
- raw pointers where they can be avoided
It seems that you want some code to treat instances of the two classes B and C
in the same way, while they're slightly different on the inside.
This is known as polymorphism.
And C++ offers two main ways to do that: compile time polymorphism (templates),
and run time polymorphism (virtual member functions).
As an example of the latter:
class IntHolder
{
private:
int c_;
public:
IntHolder( int v = 0 ): c_( v ) {}
virtual void f() = 0;
};
class B: public IntHolder
{
public:
B( int v = 0 ): IntHolder( v ) {}
virtual void f() { ... }
};
class C: public IntHolder
{
public:
C( int v = 0 ): IntHolder( v ) {}
virtual void f() { ... }
};
void foo( IntHolder& o ) { o.f(); }
int main()
{
B b;
C c;
foo( b ); foo( c );
}
Alf,
Hi, Thank you for giving me your example. It sounds like
polymorphism. I want to show you my example like polymorphism. Three
subclasses as Center share data member of base class as Top. I do not
have to use static data member. It may look like multiple diamond.
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.
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;
(b.*(b.pRun[0]))();
(b.*(b.pRun[1]))();
(b.*(b.pRun[2]))();
b.~Bottom();
return 0;
}
Output to Screen
Top()
Center1()
Center2()
Center3()
Bottom()
Center1::Run() = 1
Center2::Run() = 21
Center3::Run() = 421
~Bottom()
~Center3()
~Center2()
~Center1()
~Top()
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.