首先类的内存空间大小,只与类中非静态的成员变量(int, char*)和虚函数指针个数有关,其中函数被存放到text区域,静态成员变量存放到.rodata区域,其实也就是数据区上面的只读存储区
顺便提一下,类的所有实例化对象共享类的虚函数表,虚函数表中存放的是虚函数的指针(也就是存放函数的地址),因此虚函数表的每一项都是sizeof(pointer)的大小(32位系统就是4B,64位就是8B)
当一个类中有虚函数时,类的内存中首先会存放虚函数表的指针,其次才会存放类中的非静态成员变量
-
class Aarrt
-
{
-
int a =
1;
-
int b =
2;
-
-
virtual void vfunc() {
-
-
}
-
void print()
-
{
-
cout <<
1 <<
endl;
-
}
-
};
-
-
int main()
-
{
-
cout <<
sizeof(Aarrt) <<
endl;
-
}
类的结构如下:
, 输出为12
当类Barrt继承了一个含有虚函数的Aarrt类的时候,Barrt会继承父类的虚函数表指针,并将其转为Barrt自己的虚函数表
-
class Aarrt
-
{
-
int a =
1;
-
int b =
2;
-
-
virtual void vfunc() {
-
-
}
-
void print()
-
{
-
cout <<
1 <<
endl;
-
}
-
};
-
-
class Barrt :
public Aarrt {
-
int c =
3;
-
virtual void vfuncB() {
-
}
-
};
-
-
int main()
-
{
-
cout <<
sizeof(Barrt) <<
endl;
-
}
,输出为16.并且可以看到Derive继承了父类的虚函数表指针,并指向了自己的虚函数表
而多重继承的时候,是会保留多份虚函数指针的
-
class Base
-
{
-
int a;
-
int b;
-
public:
-
void CommonFunction();
-
void virtual VirtualFunction();
-
};
-
-
-
class DerivedClass1:
public Base
-
{
-
int c;
-
public:
-
void DerivedCommonFunction();
-
void virtual VirtualFunction();
-
};
-
-
class DerivedClass2 :
public Base
-
{
-
int d;
-
public:
-
void DerivedCommonFunction();
-
void virtual VirtualFunction();
-
};
-
-
class DerivedDerivedClass :
public DerivedClass1,
public DerivedClass2
-
{
-
int e;
-
public:
-
void DerivedDerivedCommonFunction();
-
void virtual VirtualFunction();
-
};
可以看到DerivedDerivedClass是同时保留了DerivedClass1和DerivedClass2的所有东西,因此就保存了两份虚函数表指针。这也就是为什么这种多重继承的时候有时候会导致冲突
因此引入了虚继承,虚继承就是使得多重继承的时候只保留一份公共的基类成员
然而具体实现是,每次虚继承的时候,子类单独保存父类的虚函数表指针,之后再新建一个自己的虚函数表指针。
-
class Base
-
{
-
int a;
-
int b;
-
public:
-
void CommonFunction();
-
void virtual VirtualFunction();
-
};
-
-
-
class DerivedClass1 :
virtual
public Base
-
{
-
int c;
-
public:
-
void DerivedCommonFunction();
-
void virtual VirtualFunction();
-
};
-
-
class DerivedClass2 :
virtual
public Base
-
{
-
int d;
-
public:
-
void DerivedCommonFunction();
-
void virtual VirtualFunction();
-
};
-
-
class DerivedDerivedClass :
public DerivedClass1,
public DerivedClass2
-
{
-
int e;
-
public:
-
void DerivedDerivedCommonFunction();
-
void virtual VirtualFunction();
-
};
-
int main() {
-
cout <<
sizeof(DerivedDerivedClass) <<
endl;
-
-
}
首先看DerivedClass1的类内存分布:
可以看到与public继承只保留一份基类虚函数表指针不同,子类自己创建了自己的虚函数表指针。DerivedClass2也是类似的
观看DerivedDerivedClass的内存分布为:
因为DerivedDerivedClass是public继承DerivedClass1 和2,因此是会和多继承一样继承DerivedClass1和DerivedClass2的虚函数表指针,同时只保留一份公共基类的虚函数表指针。
如果DerivedDerivedClass是virtual public继承DerivedClass1 和2,那么DerivedDerivedClass又会新建自己的虚函数表指针,同时保留父类的,其内存分布如下:
参考文献:
https://www.cnblogs.com/jerry19880126/p/3616999.html
https://blog.csdn.net/haoel/article/details/1948051 但这个文献中有一些错误,比如他说是每个对象维护一个虚函数表,但其实是每个对象维护一个公共的虚函数表指针等,但是主要汲取文章中继承时候虚函数表是如何修改的
转载:https://blog.csdn.net/mystyle_/article/details/116767988