C++之虚基类的构造函数

C++之虚基类的构造函数

#include <iostream>

using namespace std;

class A {
public:
    A(int a_parameters);

    int get_a();

private:
    int a;
};

A::A(int a_parameters) : a(a_parameters) { cout << "虚基类A构造函数创建" << endl; }

int A::get_a() { return this->a; }

class B : virtual public A {
public:
    B(int a_parameters, int b_parameters);

    int get_b();

    void display();

private:
    int b;
};

B::B(int a_parameters, int b_parameters) : A(a_parameters), b(b_parameters) {
    cout << "虚派生类B构造函数创建" << endl;
}

int B::get_b() { return this->b; }

void B::display() { cout << "a:" << get_a() << ":b:" << get_b() << endl; }

class C : virtual A {
public:
    C(int a_parameters, int c_parameters);

    int get_c();

    void display();

private:
    int c;
};

C::C(int a_parameters, int c_parameters) : A(a_parameters), c(c_parameters) {
    cout << "虚派生类C的构造函数创建" << endl;
}

int C::get_c() { return this->c; }

void C::display() { cout << "a:" << get_a() << ":c:" << get_c() << endl; }

class D : public B, public C {
public:
    D(int a_parameters, int b_parameters, int c_parameters, int d_parameters);

    int get_d();

    void display();

private:
    int d;
};

//虚继承中,间接的派生类D定义构造函数的时候,需要调用间接虚基类A(),而普通多继承中这样是不合法的。
D::D(int a_parameters, int b_parameters, int c_parameters, int d_parameters) \
: A(a_parameters), B(a_parameters, b_parameters), C(a_parameters, c_parameters), d(d_parameters) {}

int D::get_d() { return this->d; }

void D::display() {
    cout << "a:" << get_a() << ":b:" << get_b() << ":c:" << get_c() << ":d:" << get_d() << endl;
}

int main() {
    system("chcp 65001");
    B b(1, 2);
    b.display();
    C c(3, 5);
    c.display();
    D d(6, 7, 8, 9);
    d.display();
    return 0;
}
输出:
Active code page: 65001
虚基类A构造函数创建
虚派生类B构造函数创建
a:1:b:2
虚基类A构造函数创建
虚派生类C的构造函数创建
a:3:c:5
虚基类A构造函数创建
虚派生类B构造函数创建
虚派生类C的构造函数创建
a:6:b:7:c:8:d:9

上述程序中发现,在间接派生类D定义构造函数的时候,除了调用基类B和基类C的构造函数,还调用了虚基类A的构造函数,这在普通的继承中是非法的。普通的继承中间接派生类不能显示的调用间接基类A的构造函数,因为这样会造成A基类构造函数的多次初始化。
采用了虚基类后,在间接派生类D中只保留一份成员变量a,如果不调用虚基类A的构造函数,任由虚派生类B和C初始化,很有可能初始化成不同的a值,这就会导致编译器出错,不知道该调用哪个实参初始化D中的a值。
构造函数的执行顺序是首先执行虚基类A,再按照D继承时声明的顺序执行的,这和普通的多继承调用构造函数的顺序是一样的,不会由定义D构造函数的顺序决定D::D(int a_parameters, int b_parameters, int c_parameters, int d_parameters) \ : A(a_parameters), B(a_parameters, b_parameters), C(a_parameters, c_parameters), d(d_parameters) {}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值