今天主要要理解的是如下代码在内存中是如何储存/运行的:
class A
{
public:
virtual void fun1()
{
cout << "A::fun1" << endl;
}
int _a;
};
class B :virtual public A
{
public:
virtual void fun1()
{
cout << "B::fun1" << endl;
}
virtual void fun2()
{
cout << "B::fun2" << endl;
}
int _b;
};
class C :virtual public A
{
public:
virtual void fun1()
{
cout << "C::fun1" << endl;
}
virtual void fun3()
{
cout << "C::fun3" << endl;
}
int _c;
};
class D : public B, public C
{
public:
virtual void fun1()
{
cout << "D::fun1" << endl;
}
virtual void fun4()
{
cout << "D::fun4" << endl;
}
int _d;
};
int main()
{
D s;
s._a = 'a';
s._b = 'b';
s._c = 'c';
s._d = 'd';
return 0;
}
运行后函数中s的那块内存储存的内容如下图所示:
那么我们可以轻易地从中看出a,b,c,d各个变量的储存位置,那么问题来了为什么b,c,d都是按顺序储存的,可是a却储存在了最末尾,而且b,c上方都还有一块储存空间存一些好像是地址的东西这又是什么呢?
我们先进入00d2dd38地址看一下其中存储的内容如下图:
观察这两幅图不难发现0x18,和0xfffffffc是偏移量,分别指向两个地址0x010FFD90和0x010FFD70两个地址,其中储存的变分别是变量a的值和变量b上方的另一个指针。
再打开另一个指针所在的空间0x00D2DD14,结果如下图:
这中间还依旧是一串形似地址的东西,同理再去打开另外一个变量的空间,其中储存的内容如下:
又是一个地址。
通过查询资料可以了解到,继承后子类内部的储存空间会将父类各个分开储存,如下图:
其中两个地址又分别为虚表和虚基表,总结如下:
各位再见!!!!