MST

星途 面试题库

面试题:C++ 指针与内存管理及多态性结合应用

假设有一个基类 `Base` 和一个派生类 `Derived` 继承自 `Base`,在 `Base` 中有一个虚函数 `void print()`。现在编写代码创建一个 `Derived` 对象,并使用 `Base*` 指针指向它,然后调用 `print` 函数。接着动态分配一个 `Base` 数组,其中包含 `Derived` 对象和 `Base` 对象,释放内存时要避免内存泄漏,阐述在这个过程中指针在实现多态以及内存管理方面的关键作用及注意事项。
38.3万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#include <iostream>

class Base {
public:
    virtual void print() {
        std::cout << "This is Base::print()" << std::endl;
    }
    // 析构函数声明为虚函数,确保释放派生类对象时调用正确的析构函数
    virtual ~Base() {} 
};

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

int main() {
    // 创建一个Derived对象,并使用Base*指针指向它
    Base* derivedPtr = new Derived();
    derivedPtr->print(); // 调用Derived::print(),实现多态

    // 动态分配一个Base数组,其中包含Derived对象和Base对象
    Base** baseArray = new Base*[2];
    baseArray[0] = new Derived();
    baseArray[1] = new Base();

    // 遍历数组并调用print函数,实现多态
    for (int i = 0; i < 2; ++i) {
        baseArray[i]->print();
    }

    // 释放内存,避免内存泄漏
    for (int i = 0; i < 2; ++i) {
        delete baseArray[i];
    }
    delete[] baseArray;

    delete derivedPtr;

    return 0;
}

指针在实现多态方面的关键作用

  1. 基类指针指向派生类对象:通过 Base* derivedPtr = new Derived(); 这样的语句,基类指针可以指向派生类对象。在调用虚函数 print() 时,根据对象的实际类型(运行时类型)决定调用哪个类的 print 函数,这就是多态的体现。例如 derivedPtr->print(); 实际调用的是 Derived::print()
  2. 数组中的多态:在 Base** baseArray 数组中,存放了 Derived 对象和 Base 对象的指针,通过遍历数组调用 print() 函数,同样可以根据对象的实际类型调用对应的 print 函数,实现多态。

内存管理方面的注意事项

  1. 虚析构函数:在 Base 类中,析构函数必须声明为虚函数。这样当通过 Base* 指针删除派生类对象时(如 delete baseArray[i];),会调用正确的析构函数,避免内存泄漏。如果析构函数不是虚函数,通过 Base* 指针删除派生类对象时,只会调用 Base 类的析构函数,而不会调用 Derived 类的析构函数,导致派生类中分配的资源无法释放。
  2. 正确释放内存:对于动态分配的对象(如 new Derived()new Base()),要使用 delete 来释放内存;对于动态分配的数组(如 new Base*[2]),要使用 delete[] 来释放内存,以确保所有分配的内存都被正确释放,避免内存泄漏。