MST

星途 面试题库

面试题:C++含纯虚函数类的多态实现与内存管理

假设有一个基类Base包含纯虚函数,派生出若干子类Sub1、Sub2等。请实现一个函数,该函数接受Base指针作为参数,并根据实际传入的子类对象类型执行不同的操作。在此过程中,详细说明如何进行内存管理以避免内存泄漏,并且分析在这种多态实现下,虚函数表的结构和工作原理。
43.3万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 实现函数根据子类类型执行不同操作
    • 首先定义基类和子类:
#include <iostream>
class Base {
public:
    virtual void doSomething() = 0;
    virtual ~Base() {}
};

class Sub1 : public Base {
public:
    void doSomething() override {
        std::cout << "Sub1's doSomething" << std::endl;
    }
};

class Sub2 : public Base {
public:
    void doSomething() override {
        std::cout << "Sub2's doSomething" << std::endl;
    }
};
  • 然后实现根据子类类型执行不同操作的函数:
void performAction(Base* basePtr) {
    if (Sub1* sub1Ptr = dynamic_cast<Sub1*>(basePtr)) {
        sub1Ptr->doSomething();
    } else if (Sub2* sub2Ptr = dynamic_cast<Sub2*>(basePtr)) {
        sub2Ptr->doSomething();
    }
}
  1. 内存管理避免内存泄漏
    • 当使用new分配Base及其子类对象时,在不再需要这些对象时,必须使用delete来释放内存。如果通过Base指针指向子类对象,要确保Base类有虚析构函数,这样当通过Base指针delete对象时,会调用正确的子类析构函数来释放子类特有的资源。例如:
int main() {
    Base* sub1 = new Sub1();
    performAction(sub1);
    delete sub1;

    Base* sub2 = new Sub2();
    performAction(sub2);
    delete sub2;

    return 0;
}
  • 如果使用智能指针(如std::unique_ptrstd::shared_ptr),可以更安全地管理内存。例如:
#include <memory>
int main() {
    std::unique_ptr<Base> sub1 = std::make_unique<Sub1>();
    performAction(sub1.get());

    std::unique_ptr<Base> sub2 = std::make_unique<Sub2>();
    performAction(sub2.get());

    return 0;
}
  1. 虚函数表的结构和工作原理
    • 结构
      • 每个包含虚函数(包括纯虚函数)的类都有一个虚函数表(vtable)。虚函数表是一个函数指针数组。
      • 对于基类Base,虚函数表中存储了基类中虚函数的地址。如果基类有纯虚函数,虚函数表中对应的函数指针为nullptr(在实际实现中可能有特定的标识)。
      • 对于派生类,比如Sub1Sub2,它们的虚函数表首先复制基类的虚函数表内容,然后将重写的虚函数地址替换为派生类中该虚函数的实际地址。如果派生类有新的虚函数,这些函数的地址会追加到虚函数表的末尾。
    • 工作原理
      • 当创建一个包含虚函数的类对象时,对象的内存布局中会有一个隐藏的指针(vptr),该指针指向该类的虚函数表。
      • 当通过基类指针调用虚函数时,首先通过对象的vptr找到对应的虚函数表,然后根据虚函数在虚函数表中的索引找到实际要调用的函数地址,并执行该函数。例如,在performAction函数中通过Base指针调用doSomething函数时,会根据对象实际的vptr找到对应的虚函数表(如果是Sub1对象,就是Sub1的虚函数表;如果是Sub2对象,就是Sub2的虚函数表),然后调用相应的doSomething函数。