Language/C&C++
[C/C++] virtual inheritance
yhcting
2007. 3. 24. 22:18
[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]
At first, see virtual inheritance in wikipedia to know about virtual inheritance.
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.