MST

星途 面试题库

面试题:C++ 虚基类与多重继承的复杂性

在多重继承场景下,虚基类的构造函数调用顺序是怎样的?为什么要遵循这样的顺序?如果顺序不正确会导致什么问题?请通过具体代码详细阐述。
32.3万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 虚基类构造函数调用顺序

    • 在多重继承场景下,虚基类的构造函数总是先于非虚基类的构造函数被调用,并且无论虚基类在继承体系中出现多少次,它的构造函数只会被调用一次。
    • 当存在多个虚基类时,它们按照在继承列表中出现的顺序从左到右依次被构造。
  2. 遵循此顺序的原因

    • 保证虚基类的子对象在其他基类构造之前已经被正确初始化。因为虚基类可能会被多个派生类共享,如果不先初始化虚基类,在其他基类构造时使用到虚基类的成员可能会导致未定义行为。
  3. 顺序不正确可能导致的问题

    • 可能会访问到未初始化的虚基类成员,从而导致程序崩溃或产生未定义行为。
  4. 具体代码示例

#include <iostream>

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

class Base1 : virtual public VirtualBase {
public:
    Base1() {
        std::cout << "Base1 constructor" << std::endl;
    }
};

class Base2 : virtual public VirtualBase {
public:
    Base2() {
        std::cout << "Base2 constructor" << std::endl;
    }
};

class Derived : public Base1, public Base2 {
public:
    Derived() {
        std::cout << "Derived constructor" << std::endl;
    }
};

int main() {
    Derived d;
    return 0;
}

在上述代码中,VirtualBase 是虚基类,Base1Base2 都虚继承自 VirtualBaseDerived 继承自 Base1Base2。运行程序,输出结果为:

VirtualBase constructor
Base1 constructor
Base2 constructor
Derived constructor

可以看到,虚基类 VirtualBase 的构造函数首先被调用,然后是 Base1Base2 的构造函数,最后是 Derived 的构造函数。如果虚基类构造函数顺序不正确,例如先构造 Base1Base2,在它们的构造函数中若使用了 VirtualBase 的成员,就可能访问到未初始化的成员。