c++虚拟继承
来源:互联网 发布:立体图纸设计软件 编辑:程序博客网 时间:2024/06/05 19:37
http://blog.csdn.net/bluedog/article/details/4711169
先看下代码:
struct A{ A(int v=100):X(v){}; virtual void foo(void){} int X;}; struct B :virtual public A{ B(int v=10):Y(v),A(100){}; virtual void fooB(void){} int Y;}; struct C : virtual public A{ C(int v=20):Z(v),A(100){} virtual void fooC(void){} int Z;}; struct D : public B, public C{ D(int v =40):B(10),C(20),A(100),L(v){} virtual void fooD(void){} int L;}; int _tmain(int argc, _TCHAR* argv[]){ A a; int *ptr; ptr = (int*)&a; cout << ptr << " sizeof = " << sizeof(a) <<endl; for(int i=0;i<sizeof(A)/sizeof(int);i++) { if(ptr[i] < 10000) { cout << dec << ptr[i]<<endl; } else cout << hex << ptr[i] <<" = " << hex << * ((int*)(ptr[i])) <<endl; } cout << "--------------------------------------" <<endl; B b; ptr = (int*)&b; cout <<"addr:" << ptr << " sizeof = " << sizeof(b) <<endl; for(int i=0;i<sizeof(B)/sizeof(int);i++) { if(ptr[i] < 10000) { cout << dec << ptr[i]<<endl; } else cout << hex << ptr[i] <<" = " << hex << * ((int*)(ptr[i])) <<endl; } cout << "--------------------------------------" <<endl; D d; ptr = (int*)&d; cout <<"addr:" << ptr << " sizeof = " << sizeof(d) <<endl; for(int i=0;i<sizeof(D)/sizeof(int);i++) { if(ptr[i] < 10000) { cout << dec << ptr[i]<<endl; } else cout << hex << ptr[i] <<" = " << hex << * ((int*)(ptr[i])) <<endl; } return 0;}
如果B虚拟继承A,则B的对象中要增加一个虚拟基类指针,其指向的表的第二项,即从本指针到虚拟基类的偏移。
例如,对象b,的虚拟基类的地址是120+8 = 128
虚拟基类在b对象的最后。
多重继承,继承n个类,有n个续表指针;包括n个虚基类,有n个虚基类指针。
举个例子,
B虚继承A,如果A中有虚函数,则B类对象的开始位置是虚表指针,第二个位置是虚基类的指针。
class A{public: A():a(1){} int a;};class B: public virtual A{public: B():b(2){} int b;};int main() { B* b = new B; A* a = dynamic_cast<A*>(b); if(a == b)//b先默认转为A*,所以相等 { std::cout << "equal" << std::endl; } else { std::cout << "not equal" << std::endl; }//输出equal if (int(b) == int(a)) { std::cout << "equal" << std::endl; } else { std::cout << "not equal" << std::endl; }//输出not equal typedef void (*pFun)(void); int **ptb = (int **)b; cout<<ptb[0][0]<<" "<<ptb[0][1]<<endl; cout<<&((int*)ptb)[1]/*<<" "<<ptb[1][1]*/<<endl; cout<<&((int*)ptb)[2]<<endl; cout<<"-------"<<endl; cout<<a<<endl<<b<<endl;}
output:
equal
not equal
0 8
00701E5C
00701E60
-------
00701E60
00701E58
对象b的内存分布是:
虚基类的地址是 58+8 = 60
a为什么不等于b?
a指向了60的地址,而b指向的还是58
如果在虚继承的继承上又有多态重载?
class A{public: virtual void fun1() { cout<<"A"<<endl; } A():a(1){} int a;};class B: virtual public A{public: B():b(2){} virtual void fun1() { cout<<"B:fun1"<<endl; } virtual void fun2() { cout<<"B:fun2"<<endl; } int b;};int main() { B* b = new B; A* a = dynamic_cast<A*>(b); if(a == b) { std::cout << "equal" << std::endl; } else { std::cout << "not equal" << std::endl; }//输出equal if (int(b) == int(a)) { std::cout << "equal" << std::endl; } else { std::cout << "not equal" << std::endl; }//输出not equal cout<<sizeof(B)<<endl; typedef void (*pFun)(void); int **ptb = (int **)b; /* int *ptmp = (int *)b; pFun p = (pFun)((int *)ptmp[0])[0]; p();*/ pFun pfun; pfun =(pFun) ptb[0][0]; // cout<<ptb[0][0]<<" "<<ptb[0][1]<<endl; cout<<"first vtb"<<endl; pfun(); cout<<ptb[1][0]<<" "<<ptb[1][1]<<endl; cout<<((int*)ptb)[2]<<endl;//B:b cout<<(int)ptb[3]<<endl; pfun = (pFun)ptb[4][0]; cout<<"second vtb"<<endl; pfun(); cout<<((int*)ptb)[5]<<endl;//A:a cout<<"-------"<<endl; cout<<a<<endl<<b<<endl; }
output:
equal
not equal
24
first vtb
B:fun2
-4 12
2
0
second vtb
B:fun1
1
-------
00360A18
00360A08
08 vftable ---->B:fun2()
0c base_psb---->-4,12
10 B:b
14 0//不知道为什么为0?
18 vftable------>B:fun1()
1c A:a
如果B类变为
class B: virtual public A
{
public:
B():b(2){}
virtual void fun1()
{
cout<<"B:fun1"<<endl;
}
void fun2()
{
cout<<"B:fun2"<<endl;
}
int b;
};
fun2不是虚函数,所以对象b的开始不是虚函数表指针,而是虚基类指针
pFun pfun;
cout<<ptb[0][0]<<" "<<ptb[0][1]<<endl;
cout<<((int*)ptb)[1]<<endl;//B:b
pfun =(pFun) ptb[3][0];
pfun();
/*cout<<(int)ptb[3]<<endl;
pfun = (pFun)ptb[4][0];
cout<<"second vtb"<<endl;
pfun();*/
cout<<((int*)ptb)[4]<<endl;//A:a
cout<<"-------"<<endl;
cout<<a<<endl<<b<<endl;
output:
equal
not equal
20
0 12
2
B:fun1
1
-------
004D3DB4
004D3DA8
同样,为什么第2项为0?
- c++-虚拟继承、虚基类
- C++-继承:多重继承 && 虚拟继承
- 【c++】菱形虚拟虚拟继承模型探索
- C++:菱形继承和虚拟继承
- C/C++——虚拟继承
- 【C++】菱形虚拟继承(内存布局)
- C++: 虚表和菱形虚拟继承
- (虚拟继承)Problem C: 学生干部虚基类
- 【C++】菱形继承与虚拟菱形继承的对比分析
- 虚拟继承
- 虚拟继承
- 虚拟继承
- 虚拟继承
- 虚拟继承
- 虚拟继承
- 虚拟继承
- 虚拟继承
- 虚拟继承
- DirectShow
- register volatile 修饰符
- BigInteger权限判断示例
- DWR在实际项目中的应用以及在调试过程中遇到的问题
- java web 项目 推荐目录结构
- c++虚拟继承
- [转载]涉足计算机视觉领域要知道的
- linux网络编程常用函数详解与实例(socket-->bind-->listen-->accept)
- Rails一个小项目的研究笔记
- Understanding Weak References
- request的getAttribute与getParameter的区别
- 自动调节表格高度,强制换行
- eclipse 背景色调整--设置成护眼色
- OpenGL ES着色器语言之变量和数据类型(一)(官方文档第四章)