1 代码
#include <map>
#include <iostream>
#include <string>
#include <vector>
#include <climits>
#include <algorithm>
#include <math.h>
#include <utility>
using namespace std;
class A
{
public:
A()
: a1(2)
{
int i = 0;
++i;
}
virtual int do1() { return 1; }
virtual int do2() { return 2; }
int a1;
};
class B : public A
{
public:
B()
: b1(2)
{
int i = 0;
++i;
}
virtual int do1() { return 3; }
int b1;
int b2;
};
class C : public virtual A
{
public:
C()
: c1(2)
{
int i = 0;
++i;
}
virtual int do1() { return 4; }
int c1;
};
int main()
{
A *a = new A;
B *b = new B;
C *c = new C;
A *ab = b;
b->do1();
A *ac = c;
}
构造函数体中的代码没有意义只是为了解释代码执行的顺序。
首先看:

汇编:

上面最后一个注释错了,rbx是申请的内存,构造函数没有返回值,因此rbx直接赋值给指针a了。
然后看A:A()

(至于为什么是:OFFSET FLAT:vtable for B+16 。抱歉不知道啊。查到的时候再补)
紧接着看看 vtable for A 是什么:

然后再看:

这里A就算构造结束,还算是简单。
看B的构造

汇编

可以非虚继承就是在派生类的内存空间上依次调用基类的构造函数。基类的数据成员在派生类中依次摆放。并且派生类的数据成员的偏移在编译阶段就确定好了。
虚继承