At first, see virtual inheritance in wikipedia to know about virtual inheritance.
There are lots of articles about this. So, I am adding 'Real' example tested on "MSVC2005 Express".
- Don't use 'debug watch' of VC. Sometimes it show wrong information!.
(Note: C++ standard doens't define anything about the way of implementing dynamic polymorphism. So, results are dependent on compiler.)
================================== Non-Virtual Inheritance class Animal { virtual void Eat(){}; int animal; }; Animal +-----------------+ | __vfptr |---> Animal::Eat() +-----------------+ | int animal | +-----------------+ class Mammal : public Animal { virtual void Run(){}; int mammal }; Mammal +-----------------+ | __vfptr |---> Animal::Eat() +-----------------+ Mammal::Run() | int animal | +-----------------+ | int mammal | +-----------------+ class Winged : public Animal { virtual void Flap(){}; int winged }; Winged +-----------------+ | __vfptr |---> Animal::Eat() +-----------------+ Winged::Flap() | int animal | +-----------------+ | int winged | +-----------------+ class Bat : public Mammal, public Winged { virtual void Hang(){}; }; Bat +-----------------+ | __vfptr |---> Animal::Eat() (*1) [from Mammal] +-----------------+ Mammal::Run() | int animal | Bat::Hang() +-----------------+ | int mammal | +-----------------+ | __vfptr |---> Animal::Eat() (*2) [from Winged] +-----------------+ Winged::Flap() | int animal | +-----------------+ | int winged | +-----------------+ (Address of (*1) and (*2) is different.) ====================================== Virtual Inheritance class Animal { public: Animal():animal(){} virtual void Eat(){}; int animal; }; Animal +-----------------+ | __vfptr |---> Animal::Eat() +-----------------+ | int animal | +-----------------+ class Mammal : public virtual Animal { public: Mammal():mammal(){} virtual void Run(){}; int mammal; }; Mammal +-----------------+ | __vfptr |---> Mammal::Run() +-----------------+ | ??????????? | +-----------------+ | int mammal | +-----------------+ | __vfptr |---> Animal::Eat() +-----------------+ | int animal | +-----------------+ class Winged : public virtual Animal { public: Winged():winged(){} virtual void Flap(){}; int winged; }; Winged +-----------------+ | __vfptr |---> Winged::Flap() +-----------------+ | ??????????? | +-----------------+ | int winged | +-----------------+ | __vfptr |---> Animal::Eat() +-----------------+ | int animal | +-----------------+ class Bat : public Mammal, public Winged { virtual void Hang(){}; }; Bat +-----------------+ | __vfptr |---> Mammal::Run() +-----------------+ Bat::Hang() | ?????????? | +-----------------+ | int mammal | +-----------------+ | __vfptr |---> Winged::Flap() +-----------------+ | ?????????? | +-----------------+ | int winged | +-----------------+ | __vfptr |---> Animal::Eat() +-----------------+ | int animal | +-----------------+ ===============================NOTE: I have no idea what "?????" means. I think this is only for internal use of VC.
Here is view of this.
"---." : reference member (p.xxx) "--->" : pointer member (p->xxx) Non-virtual inheritance bat |----. Mammal | |----. Animal | | |----. __vfptr ( --> 0x00415770) --- (*1) | | | |----> Animal::eat(void) | | | |----> Mammal::setHairColor(void) | |----. WingedAnimal | |----. Animal | | |----. __vfptr ( --> 0x00415760) --- (*2) | | | |----> Animal::eat(void) | | | |----> WingedAnimal::flap(void) Virtual inheritance case bat |----. Mammal | |----. Animal | | |----. __vfptr ( --> 0x00415788) --- (*3) | | | |----> Animal::eat(void) | |----. __vfptr | | |----> Mammal::setHairColor(void) | |----. WingedAnimal | |----. Animal | | |----. __vfptr ( --> 0x00415788) --- (*4) | | | |----> Animal::eat(void) | |----. __vfptr | | |----> WingedAnimal::flap(void)
We should focus on that pointed address indicated at (*1) and (*2) is different, but the one at (*3) and (*4) is same - actually, it's not separated entity, it's same one. That is, there is one vftable for Animal class.
Now we can know the way of virtual inheritance.
'Language > C&C++' 카테고리의 다른 글
[C/C++] Avoiding symbol conflict when release library... (0) | 2007.05.19 |
---|---|
[C/C++] Using 'virtual' and 'inline' keywords simultaneously. (0) | 2007.04.04 |
[C/C++] Remind! Multiple-Inheritance of same-named-method from two classes. (0) | 2007.03.18 |
[C/C++] Remind! '>>' extends sign bit (0) | 2007.01.11 |
[C/C++][Tip] Using long and important 'enum'.. (0) | 2006.12.03 |