📜  C++中的虚拟基类(1)

📅  最后修改于: 2023-12-03 15:29:54.662000             🧑  作者: Mango

C++中的虚拟基类

在C++中,虚拟基类(Virtual Base Class)是一种用于解决多重继承中“菱形继承”问题的技术。

菱形继承问题

菱形继承问题指的是,在多重继承时,如果两个父类都继承自同一个基类,那么在子类中就会出现多个相同的基类,从而导致数据冗余和访问二义性。

例如,有以下类的继承关系:

class A {
public:
    int a;
};

class B : public A {
public:
    int b;
};

class C : public A {
public:
    int c;
};

class D : public B, public C {
public:
    int d;
};

在上述继承关系中,类D继承了类B和类C,但是类B和类C都继承了类A,因此在类D中就会出现两份相同的类A的子对象,即“菱形”形状。如果访问类A的成员变量时没有明确指定从哪个父类继承的,就会出现访问二义性的问题。

虚拟基类的定义和使用

虚拟基类是一种被声明为虚拟的基类,它的子类只继承一份该虚拟基类的成员,从而解决了菱形继承问题。在类定义中,可以使用关键字virtual来声明某个基类为虚拟基类。

例如,将类A声明为虚拟基类,就可以避免在类D中出现两份相同的类A子对象:

class B : virtual public A { // 基类A被声明为虚拟基类
public:
    int b;
};

class C : virtual public A {
public:
    int c;
};

class D : public B, public C {
public:
    int d;
};

在上述代码中,类B和类C都重写声明了类A为虚拟基类,因此在类D中只有一份类A的子对象,从而避免了菱形继承问题。

虚拟基类的构造函数调用

在虚拟基类中,构造函数只会被调用一次,而不是每个子类都调用一次。

例如,在以下代码中,类B和类C都继承了虚拟基类A,并且都需要调用A的构造函数:

class A {
public:
    A() { cout << "A constructor" << endl; }
};

class B : virtual public A {
public:
    B() { cout << "B constructor" << endl; }
};

class C : virtual public A {
public:
    C() { cout << "C constructor" << endl; }
};

class D : public B, public C {
public:
    D() { cout << "D constructor" << endl; }
};

当创建一个类D的对象时,程序会先调用类A的构造函数,然后调用类B和类C的构造函数,最后调用类D的构造函数。因此,输出结果为:

A constructor
B constructor
C constructor
D constructor
总结

虚拟基类是一种用于解决多重继承中菱形继承问题的技术,它可以避免在子类中出现多个相同的基类,从而避免数据冗余和访问二义性。在使用虚拟基类时,需要注意虚拟基类的构造函数只会被调用一次。