派生类构造函数顺序
函数执行顺序
构造函数执行顺序:
- 虚基类构造函数
- 普通基类构造函数
- 成员变量构造函数
析构函数执行顺序:
与构造函数相反顺序
#include "iostream"
using namespace std;
class base
{
public:
base() { cerr << __PRETTY_FUNCTION__ << endl; }
~base() { cerr << __PRETTY_FUNCTION__ << endl; }
void fun() { cerr << __PRETTY_FUNCTION__ << endl; }
};
class base1
{
public:
base1() { cerr << __PRETTY_FUNCTION__ << endl; }
~base1() { cerr << __PRETTY_FUNCTION__ << endl; }
void fun() { cerr << __PRETTY_FUNCTION__ << endl; }
};
class vbase
{
public:
vbase() { cerr << __PRETTY_FUNCTION__ << endl; }
~vbase() { cerr << __PRETTY_FUNCTION__ << endl; }
void fun() { cerr << __PRETTY_FUNCTION__ << endl; }
};
class drive : public base, virtual public vbase, public base1
{
public:
drive() { cerr << __PRETTY_FUNCTION__ << endl; }
~drive() { cerr << __PRETTY_FUNCTION__ << endl; }
void fun() { cerr << __PRETTY_FUNCTION__ << endl; }
};
int main()
{
drive d;
}
虚继承
基类可以是虚基类(添加virtual 继承),虚基类的作用在菱形继承情况下能发挥作用。
例如:
// 基类:
class A { public: void func(){}}
// 单继承:
class B1: public A { public: }
class B2: public A { public: }
// 普通多继承:
class D: public B1, public B2 { public: }
如上:类 D 继承了 B1 与 B2,而二者都从基类 A 派生出来,所以 A,B 都继承了成员函数 func(),这时候就会存在下图(b)的情况,如果为虚继承则是(a)的情况。
普通多继承就会存在一个问题,在 D 中不能直接调用 func 函数,因为会发生歧义,到底是调用 B1 还是B2 中的函数。而虚继承则解决了这个问题。
虚继承解决的原理可以理解为“编译器延迟对虚基类的初始化,直到继承的末尾才初始化”,也就是由最后一个类,在本例就是 D 里来初始化 A(基于这个原理思考下,怎么利用虚继承实现不可继承的类)
测试代码:
#include "iostream"
using namespace std;
class base
{
public:
base() { cerr << __PRETTY_FUNCTION__ << endl; }
~base() { cerr << __PRETTY_FUNCTION__ << endl; }
void fun() { cerr << __PRETTY_FUNCTION__ << endl; }
};
class base1 : virtual public base
{
public:
base1() { cerr << __PRETTY_FUNCTION__ << endl; }
~base1() { cerr << __PRETTY_FUNCTION__ << endl; }
};
class base2 : virtual public base
{
public:
base2() { cerr << __PRETTY_FUNCTION__ << endl; }
~base2() { cerr << __PRETTY_FUNCTION__ << endl; }
};
class drive : public base1, public base2
{
public:
drive() { cerr << __PRETTY_FUNCTION__ << endl; }
~drive() { cerr << __PRETTY_FUNCTION__ << endl; }
};
int main(int argc, char *argv[])
{
drive d;
d.fun();
return 0;
}