MST

星途 面试题库

面试题:C++中动态关联如何通过虚函数和指针/引用实现

请解释在C++ 中,当使用虚函数时,如何通过指针或引用调用函数来实现动态关联。请给出一个简单的代码示例,并分析其运行时动态关联的过程。
38.8万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 动态关联的原理
    • 在C++中,当类中定义虚函数时,每个包含虚函数的类及其派生类对象都有一个虚函数表(vtable)。虚函数表是一个函数指针数组,存储了类中虚函数的地址。
    • 当通过指针或引用调用虚函数时,程序在运行时会根据指针或引用所指向对象的实际类型,去该对象对应的虚函数表中查找并调用相应的虚函数,这就是动态关联,也称为运行时多态。
  2. 代码示例
#include <iostream>

class Base {
public:
    virtual void print() {
        std::cout << "This is Base class." << std::endl;
    }
};

class Derived : public Base {
public:
    void print() override {
        std::cout << "This is Derived class." << std::endl;
    }
};

int main() {
    Base* basePtr;
    Derived derivedObj;

    basePtr = &derivedObj;
    basePtr->print(); // 通过指针调用虚函数

    Base& baseRef = derivedObj;
    baseRef.print(); // 通过引用调用虚函数

    return 0;
}
  1. 运行时动态关联过程分析
    • 在上述代码中,Base类定义了一个虚函数printDerived类从Base类派生,并覆盖(override)了print函数。
    • main函数中,首先定义了一个Base类型的指针basePtr和一个Derived类型的对象derivedObj
    • basePtr = &derivedObj;时,basePtr指向了derivedObj。虽然basePtr的静态类型是Base*,但它实际指向的是Derived类型的对象。
    • 当调用basePtr->print();时,由于print是虚函数,程序在运行时会根据basePtr实际指向的Derived类型对象,去Derived类的虚函数表中查找print函数的地址,并调用Derived类中的print函数,输出This is Derived class.
    • 对于引用Base& baseRef = derivedObj;,同样的原理,baseRef实际引用的是Derived类型的对象,调用baseRef.print();时,也会在运行时根据对象的实际类型(Derived)去虚函数表中查找并调用Derived类的print函数。