c++内存部局(虚继承)
时间:2014-05-09 01:08:07
收藏:0
阅读:488
最近又重新温习了一下深度探索c++对象模型,中虚拟继承虚表的实现,为了弄清虚表的内存部局情况特写此测试程序。
测试程序分别在windows vs2012下,与linux gcc 4..4.7 20120313 redhat4.4.7-4下
windows vs2012
上图中的偏移为-4表明存在vptr,如果为0说明没有vptr,下面的程序可以说明,而且从图中可以看出虚表中不会有重复的选项
#include <iostream>
using namespace std;
class X{
public:
virtual void funcx(){cout << "X::funcx" << endl;}
};
class Y:public virtual X{
public:
virtual void funcy(){cout << "Y::funcy" << endl;}
virtual void funcx(){cout << "Y::funcx" << endl;}
};
class Z:public virtual X{
public:
virtual void funcz(){cout << "Z::funcz" << endl;}
virtual void funcx(){cout << "Z::funcx" << endl;}
};
class D:public Y, public Z{
public:
virtual void funcd(){cout << "D::funcd" << endl;}
virtual void funcx(){cout << "D::funcx" << endl;}
};
typedef void (*func)();
int main(){
func fptr;
cout << "sizeof(X) = " << sizeof(X) << endl;
cout << "sizeof(Y) = " << sizeof(Y) << endl;
cout << "sizeof(Z) = " << sizeof(Z) << endl;
cout << "sizeof(D) = " << sizeof(D) << endl;
D d;
int *vptr = (int*)&d;
int *f = (int*)(vptr[0]);
cout << "-----------------------" << endl;
fptr = (func)(f[0]); fptr();
fptr = (func)(f[1]); fptr();
cout << "-----------------------" << endl;
f = (int*)(vptr[1]);
cout << *f << endl;
cout << "-----------------------" << endl;
f = (int*)(vptr[2]);
fptr = (func)(f[0]); fptr();
cout << "-----------------------" << endl;
f = (int*)(vptr[3]);
cout << *f << endl;
cout << "-----------------------" << endl;
f = (int*)(vptr[4]);
fptr = (func)(f[0]); fptr();
return 0;
}
#include <iostream>
using namespace std;
class X{
public:
virtual void funcx(){cout << "X::funcx" << endl;}
};
class Y:public virtual X{
public:
virtual void funcy(){cout << "Y::funcy" << endl;}
virtual void funcx(){cout << "Y::funcx" << endl;}
};
class Z:public virtual X{
public:
//virtual void funcz(){cout << "Z::funcz" << endl;} //对此处进行注释
//virtual void funcx(){cout << "Z::funcx" << endl;} //对此处进行注释 那么就没有了Z 的vptr 但有仍有其指向偏移的指针
};
class D:public Y, public Z{
public:
virtual void funcd(){cout << "D::funcd" << endl;}
virtual void funcx(){cout << "D::funcx" << endl;}
};
typedef void (*func)();
int main(){
func fptr;
cout << "sizeof(X) = " << sizeof(X) << endl;
cout << "sizeof(Y) = " << sizeof(Y) << endl;
cout << "sizeof(Z) = " << sizeof(Z) << endl;
cout << "sizeof(D) = " << sizeof(D) << endl;
D d;
int *vptr = (int*)&d;
int *f = (int*)(vptr[0]);
cout << "-----------------------" << endl;
fptr = (func)(f[0]); fptr();
fptr = (func)(f[1]); fptr();
cout << "-----------------------" << endl;
f = (int*)(vptr[1]);
cout << *f << endl;
cout << "-----------------------" << endl;
//f = (int*)(vptr[2]);
//fptr = (func)(f[0]); fptr();
cout << "-----------------------" << endl;
f = (int*)(vptr[2]);
cout << *f << endl;
cout << "-----------------------" << endl;
f = (int*)(vptr[3]);
fptr = (func)(f[0]); fptr();
return 0;
}
Linux gcc 4.4.7
此图为linux下的虚继承的内存部局图, 图中可以看出虚表中有重得的选项,但是此图可以看出它相对于win下的部局它没有偏移的指针
#include <iostream>
using namespace std;
class X{
public:
virtual void funcx(){cout << "X::funcx" << endl;}
};
class Y:public virtual X{
public:
virtual void funcy(){cout << "Y::funcy" << endl;}
virtual void funcx(){cout << "Y::funcx" << endl;}
};
class Z:public virtual X{
public:
virtual void funcz(){cout << "Z::funcz" << endl;}
virtual void funcx(){cout << "Z::funcx" << endl;}
};
class D:public Y, public Z{
public:
virtual void funcd(){cout << "D::funcd" << endl;}
virtual void funcx(){cout << "D::funcx" << endl;}
};
typedef void (*func)();
int main(){
func fptr;
cout << "sizeof(X) = " << sizeof(X) << endl;
cout << "sizeof(Y) = " << sizeof(Y) << endl;
cout << "sizeof(Z) = " << sizeof(Z) << endl;
cout << "sizeof(D) = " << sizeof(D) << endl;
D d;
int *vptr = (int*)&d;
int *f = (int*)(vptr[0]);
cout << "-----------------------" << endl;
fptr = (func)(f[0]); fptr();
fptr = (func)(f[1]); fptr();
cout << "-----------------------" << endl;
f = (int*)(vptr[1]);
cout << *f << endl;
cout << "-----------------------" << endl;
f = (int*)(vptr[2]);
fptr = (func)(f[0]); fptr();
cout << "-----------------------" << endl;
f = (int*)(vptr[3]);
cout << *f << endl;
cout << "-----------------------" << endl;
f = (int*)(vptr[4]);
fptr = (func)(f[0]); fptr();
return 0;
}从图中能够反应出,类的大小与win的差距还是很大的
评论(0)