虚表机制
普通继承
此种情况下对象模型是简单的
#include<iostream>
class Top
{
public:
int a;
};
class Left:public Top
{
public:
int b;
};
class Right:public Top
{
public:
int c;
};
class Bottom:public Left, public Right
{
public:
int d;
};
int main()
{
std::cout << "hello world!" << std::endl;
/*
对象模型:
Top Left Right Bottom
Top::a Top::a Top::a Left::Top::a
Left::b Right::c Left::b
Right::Top::a
Right::c
Bottom::d
*/
Left* left = new Left();
Top* top = left; //指针向上转型
//std::cout << top->a << std::endl; //ok
//std::cout << top->b << std::endl; //err:类Top没有b成员
std::cout << "指针left的值:" << left << " 指针top的值:" << top << std::endl; //两值相同
Bottom* bottom = new Bottom();
left = bottom; //指针向上转型
//std::cout << left->a << std::endl; //ok
//std::cout << left->b << std::endl; //ok
//std::cout << left->d << std::endl; //err:类Left没有d成员
std::cout << "指针bottom的值:" << bottom << " 指针left的值:" << left << std::endl; //两值相同
Right* right = bottom; //指针向上转型
//std::cout << right->a << std::endl; //ok
//std::cout << right->c << std::endl; //ok
//std::cout << right->d << std::endl; //err:类Right没有d成员
std::cout << "指针bottom的值:" << bottom << " 指针right的值:" << right << std::endl; //两值不同,right=bottom+偏移量8
//top = bottom; //err:基类Top不明确,'Top' is an ambiguous base of 'Bottom'
Top* topL = (Left*) bottom; //ok
Top* topR = (Right*) bottom; //ok
std::cout << "指针topL的值:" << bottom << " 指针left的值:" << left << std::endl; //两值相同
std::cout << "指针topR的值:" << bottom << " 指针right的值:" << right << std::endl; //两值相同
return 0;
}
虚继承
虚继承可以用来避免重复继承
//虚继承可以避免重复继承基类
#include<iostream>
class Top
{
public:
int a;
};
class Left:virtual public Top
{
public:
int b;
};
class Right:virtual public Top
{
public:
int c;
};
class Bottom:public Left, public Right
{
public:
int d;
};
int main()
{
std::cout << "hello world!" << std::endl;
/*
对象模型:
Top
Top::a:int
Left points to vtable for Left
vptr.Left:vtable for Left----------------->virtual base offset:int=8
Left::b:int offset to top:int=0
Top::a:int typeinfo:typeinfo for Left
Right points to vtable for Right
vptr.Right:vtable for Right----------------->virtual base offset:int=8
Right::c:int offset to top:int=0
Top::a:int typeinfo:typeinfo for Right
Bottom points to vtable for Bottom
vptr.Left:vtable for Bottom-------------------->virtual base offset:int=20
Left::b:int points to offset to top:int=0
vptr.Right:vtable for Bottom---------+ typeinfo:typeinfo for Bottom
Right::c:int +--------> virtual base offset:int=12
Bottom::d:int offset to top:int=8
Top::a:int typeinfo:typeinfo for Bottom
*/
Bottom* bottom = new Bottom();
Left* left = bottom;
//std::cout << left->a << std::endl; //ok
//std::cout << left->b << std::endl; //ok
//std::cout << left->d << std::endl; //err:类Left没有d成员
std::cout << "指针bottom的值:" << bottom << " 指针left的值:" << left << std::endl; //两值相同,left=bottom
std::cout << "left->b的地址值:" << &left->b << " left->a的地址值:" << &left->a << std::endl; //两值不同
Right* right =bottom;
//std::cout << right->a << std::endl; //ok
//std::cout << right->c << std::endl; //ok
//std::cout << right->d << std::endl; //err:类Right没有d成员
std::cout << "指针bottom的值:" << bottom << " 指针right的值:" << right << std::endl; //两值不同,right=bottom+偏移量16
std::cout << "right->c的地址值:" << &right->c << " right->a的地址值:" << &right->a << std::endl; //两值不同
std::cout << "bottom->b的地址值:" << &bottom->b << " bottom->c的地址值:" << &bottom->c << " bottom->d的地址值:" << &bottom->d << " bottom->a的地址值:" << &bottom->a <<std::endl;
left = new Left();
//std::cout << left->a << std::endl; //ok
//std::cout << left->b << std::endl; //ok
//std::cout << left->d << std::endl; //err:类Left没有d成员
std::cout << "left的地址:" << left << " left->b的地址值:" << &left->b << " left->a的地址值:" << &left->a << std::endl; //两值不同
return 0;
}
参考:https://www.cnblogs.com/qg-whz/p/4909359.html
https://www.oschina.net/translate/cpp-virtual-inheritance?comments&p=5