您的位置:首页 > 编程语言 > C语言/C++

C++ 虚函数和多重继承的内存布局初探

2013-09-23 16:31 501 查看

C++ 对象的内存布局

一切以事实说话:

代码:

[code] #include <stdio.h>


 


class A {


public:


int a;


int b;


int c;


};


 


int main(int argc, char** argv) {


A obj;


printf(" obj   :%p\n obj.a: %p \n obj.b: %p \n obj.c: %p\n" ,


&obj, &obj.a, &obj.b, &obj.c);


return 0;


}

[/code]

执行结果:





不同的机器执行的结果可能不同,但是从这里的出的一个结论是:

对象的地址是整个类的起始地址(也就是低地址)。其成员的地址顺序和其在类中声明的顺序有关系。

而对上面的代码稍加修改,增加一个虚函数。

[code] #include <stdio.h>


 


class A { 


public:


virtual void show() {}


int a;


int b;


int c;


};


 


int main(int argc, char** argv) {


A obj;


printf(" obj   :%p\n obj.a: %p \n obj.b: %p \n obj.c: %p\n" ,


&obj, &obj.a, &obj.b, &obj.c);


return 0;


}

[/code]

测试结果:





这里是由于增加了一个虚函数表的指针(测试机器为64位系统,故指针为8个字节)。从这里可以看出,虚函数表指针在类的起始地址,这也是为了对于不同的类该地址的偏移相同。

[code] class X {


};


class Y {


public:


virtual void f() {};


};


class X1 : public virtual X {


};


class X2 : public virtual X {


};


class A1 : public X1, public X2 {


};


class X3 : public X {


};


class X4 : public X {


};


class A2 : public X3, public X4 {


};


class Y1 : public virtual Y {


};


class Y2 : public virtual Y {


};


class B1 : public Y1, public Y2 {


};


class Y3 : public Y {


};


class Y4 : public Y {


};


class B2 : public Y3, public Y4 {


};


 


int main (int argc, char** argv) {


printf("sizeof(X) %lu\n", sizeof(X));


printf("sizeof(Y) %lu\n", sizeof(Y));


printf("sizeof(X1) %lu\n", sizeof(X1));


printf("sizeof(X2) %lu\n", sizeof(X2));


printf("sizeof(A1) %lu\n", sizeof(A1));


printf("sizeof(X3) %lu\n", sizeof(X3));


printf("sizeof(X4) %lu\n", sizeof(X4));


printf("sizeof(A2) %lu\n", sizeof(A2));


printf("sizeof(Y1) %lu\n", sizeof(Y1));


printf("sizeof(Y2) %lu\n", sizeof(Y2));


printf("sizeof(B1) %lu\n", sizeof(B1));


printf("sizeof(Y3) %lu\n", sizeof(Y3));


printf("sizeof(Y4) %lu\n", sizeof(Y4));


printf("sizeof(B2) %lu\n", sizeof(B2));


return 0;


}        

[/code]

执行结果:





上面的测试结果得出的结论:

空类的大小不是0,而是1,这样是提供一个占位符,这样由空类创建出的两个对象的地址就会不同,以作区分。

当类不是空的时候,该占位符就不需要了,类的大小就是类中成员所需的空间大小

注: 本想深入一探究竟,不过这部分和编译器有很大的关系,非朝夕可以搞定。先写这么多,再多做了解后再补充吧。

refer:

/article/2551888.html

/article/2551889.html

http://blog.chinaunix.net/uid-22535463-id-2749544.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: