虚函数 虚继承 C++ vc ++ g++内存区别
本人使用的是vc,根据阅读其他人的文章以及自己的实际验证,
目前,了解到的区别主要有两点:
大致说明虚函数与虚继承:
父类如果有虚函数,在父类对象的内存中会有一个vfptr指向虚函数的位置;
子类虚继承于父类,子类会拥有一个vbptr记录偏移量。
子类虚继承父类,会将父类的vfptr一并继承,例如父类有两个int,那子类对象里面就会有12个来自父类的字节,两个int和一个vfptr。
同时自己会有一个vbptr和自己的数据,比如说两个int,这里的子类就是12+12(自己的两个int和一个vbptr)。
如果是gcc,这里就结束了
vc就不一样了,这也是我怎么算都算不对的原因。
1.在gcc编译器下,父类与子类是共享vfptr的,也就是说,无论子类有没有重新构造虚函数,或者加入新的虚函数。
例如:vfptr->student::fun1() person::fun2() student::fun3()
而vc编译器下,子类虚继承于父类的情况下,子类的vfptr有两种情况,如果
有加入新函数子类将不与父类共享vfptr
vfptr->student::fun1() person::fun2()
vfptr->student::fun3()
如果没有加入新函数则没有影响
vfptr->student::fun1() person::fun2() 。
2.在vc编译器下,子类虚继承于父类,子类内存与父类内存之间会有一个4个字节的(vtordisp for vbase xxx)。
这里附带一个我自己测试菱形继承的例子。
1 class Car; 2 class Person 3 { 4 5 protected: 6 int m_age; 7 int m_sex; 8 9 10 public: 11 Person(); 12 Person(int age,int sex); 13 virtual ~Person(); 14 void setAge(int age); 15 int getAge(); 16 virtual void speak(); 17 virtual void run(); 18 };
1 #include "Person.h" 2 class Worker :public virtual Person 3 { 4 protected: 5 int m_salary; 6 public: 7 Worker(); 8 Worker(int age, int sex, int salary); 9 ~Worker(); 10 void speak(); 11 void run(); 12 13 };
1 #include "worker.h" 2 #include "Student.h" 3 class WorkStudent :public Worker,public Student 4 { 5 int int1; 6 public: 7 WorkStudent(); 8 WorkStudent(int age, int sex, int salary,int no, int test,int int1); 9 ~WorkStudent(); 10 void speak(); 11 void run(); 12 13 };
1 #include "Person.h" 2 class Student :public virtual Person 3 { 4 protected: 5 int m_age; 6 int m_sex; 7 int m_no; 8 int m_test; 9 public: 10 Student(); 11 Student(int age, int sex, int no,int test); 12 ~Student(); 13 void speak(); 14 void run(); 15 virtual void learn(); 16 17 };
大小分别是12,40,24,52
12=4+4+vfptr
40=[4vfptr(因为有新的虚函数,所以有一个属于自己的vfptr)+4vbptr+4*4]+4(vtordisp)+12(父类)
24=[4vbptr+4]+4(vtordisp)+12(父类)
注意这里的Worker是没有新的虚函数,所以是与父类里的vfptr共用。
52=40+24 - (4(vtordisp)+12(父类))
符合虚继承的作用,只有一份person类的内容。
这里贴一份用
/d1 reportSingleClassLayoutXX (XX就是类名)
打出来的内容
1>class WorkStudent size(52):
1> +---
1> 0 | +--- (base class Student)
1> 0 | | {vfptr}
1> 4 | | {vbptr}
1> 8 | | m_age
1>12 | | m_sex
1>16 | | m_no
1>20 | | m_test
1> | +---
1>24 | +--- (base class Worker)
1>24 | | {vbptr}
1>28 | | m_salary
1> | +---
1>32 | int1
1> +---
1>36 | (vtordisp for vbase Person)
1> +--- (virtual base Person)
1>40 | {vfptr}
1>44 | m_age
1>48 | m_sex
1> +---
浙公网安备 33010602011771号