MST

星途 面试题库

面试题:C++成员函数在多态场景下对对象数据区分的机制

考虑如下场景,有一个基类 `Base` 包含成员变量 `int baseData;` 和虚成员函数 `void displayData();`,派生类 `Derived` 继承自 `Base` 并新增成员变量 `int derivedData;` 且重写 `displayData` 函数。当通过基类指针数组 `Base* arr[2];` 分别指向 `Base` 对象和 `Derived` 对象时,在 `displayData` 函数中是如何准确区分并展示各自对象的数据的?请详细阐述底层原理,并给出完整的代码示例。
27.1万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 底层原理
    • 在C++中,通过虚函数和动态绑定机制来实现这种区分。当基类中声明了虚函数,派生类重写该虚函数时,对象的实际类型(而非指针类型)决定了运行时调用哪个版本的虚函数。
    • 每个包含虚函数的类都有一个虚函数表(vtable),其中存储了虚函数的地址。对象的内存布局中,在开始位置会有一个指向其所属类的虚函数表的指针(vptr)。当通过基类指针调用虚函数时,首先通过vptr找到对应的虚函数表,然后在虚函数表中找到要调用的虚函数的实际地址并执行。
  2. 代码示例
#include <iostream>

class Base {
public:
    int baseData;
    Base(int data) : baseData(data) {}
    virtual void displayData() {
        std::cout << "Base class data: " << baseData << std::endl;
    }
};

class Derived : public Base {
public:
    int derivedData;
    Derived(int base, int derived) : Base(base), derivedData(derived) {}
    void displayData() override {
        std::cout << "Derived class data - baseData: " << baseData << ", derivedData: " << derivedData << std::endl;
    }
};

int main() {
    Base* arr[2];
    arr[0] = new Base(10);
    arr[1] = new Derived(20, 30);

    for (int i = 0; i < 2; ++i) {
        arr[i]->displayData();
        delete arr[i];
    }

    return 0;
}

在上述代码中,Base类的displayData函数被声明为虚函数,Derived类重写了该函数。在main函数中,通过基类指针数组分别指向Base对象和Derived对象,并调用displayData函数,实际调用的是对应对象实际类型的displayData函数版本,从而准确区分并展示各自对象的数据。