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