MST

星途 面试题库

面试题:C++ 虚函数动态绑定在多重继承场景下的表现

在 C++ 的多重继承体系中,假设有类 A、B、C,其中 C 继承自 A 和 B,A 和 B 都有虚函数 `virtual void func()`。在 C 类中重写该虚函数,当通过指向 C 类对象的 A 类指针和 B 类指针分别调用 `func()` 时,动态绑定是如何实现的?请详细分析并通过代码展示结果及解释。
46.3万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 动态绑定原理分析
    • 在 C++ 中,动态绑定是通过虚函数表(vtable)和虚函数表指针(vptr)来实现的。
    • 当一个类包含虚函数时,编译器会为该类生成一个虚函数表。虚函数表是一个存储虚函数地址的数组。
    • 每个包含虚函数的类的对象都有一个虚函数表指针(vptr),该指针指向对应的虚函数表。
    • 在多重继承中,C 类继承自 A 和 B,C 类对象会有两个虚函数表指针,分别对应 A 和 B 的虚函数表(因为 A 和 B 都有虚函数)。
    • 当通过 A 类指针调用 func() 时,会根据 A 类虚函数表指针找到对应的虚函数表,然后调用其中 func() 的地址,由于 C 类重写了 func(),所以调用的是 C 类中的 func() 实现。同理,通过 B 类指针调用 func() 时,会根据 B 类虚函数表指针找到 B 类虚函数表,进而调用 C 类中重写的 func() 实现。
  2. 代码示例
#include <iostream>

class A {
public:
    virtual void func() {
        std::cout << "A::func()" << std::endl;
    }
};

class B {
public:
    virtual void func() {
        std::cout << "B::func()" << std::endl;
    }
};

class C : public A, public B {
public:
    void func() override {
        std::cout << "C::func()" << std::endl;
    }
};

int main() {
    C c;
    A* aPtr = &c;
    B* bPtr = &c;

    aPtr->func();
    bPtr->func();

    return 0;
}
  1. 代码结果及解释
    • 结果:运行上述代码,输出结果为:
C::func()
C::func()
  • 解释
    • aPtr->func() 执行时,aPtr 是 A 类指针,它指向 C 类对象 c。根据动态绑定机制,它会通过 C 类对象中与 A 类相关的虚函数表指针找到虚函数表,然后调用 C 类中重写的 func() 函数,所以输出 C::func()
    • 同理,当 bPtr->func() 执行时,bPtr 是 B 类指针,它也指向 C 类对象 c。通过 C 类对象中与 B 类相关的虚函数表指针找到虚函数表,调用 C 类中重写的 func() 函数,输出同样是 C::func()。这体现了在多重继承体系下,通过不同基类指针调用重写虚函数时动态绑定的正确实现。