MST

星途 面试题库

面试题:C++ 中 std::unique_ptr 管理多态对象数组的问题及解决

当使用 std::unique_ptr 管理多态对象数组时,会遇到什么问题?如何解决这个问题?请详细阐述原理,并提供示例代码。
13.2万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 问题
    • 当使用std::unique_ptr管理多态对象数组时,由于std::unique_ptr默认的删除器使用delete而不是delete[],在析构数组时会导致未定义行为。因为delete用于释放单个对象,delete[]用于释放数组对象,对数组对象使用delete会造成内存错误。
  2. 解决方法
    • 可以自定义删除器,让std::unique_ptr使用delete[]来释放数组。
  3. 原理
    • std::unique_ptr的第二个模板参数是删除器类型。通过提供一个使用delete[]的删除器,我们可以确保在std::unique_ptr析构时,多态对象数组能被正确释放。
  4. 示例代码
#include <iostream>
#include <memory>

class Base {
public:
    virtual ~Base() { std::cout << "Base destructor" << std::endl; }
};

class Derived : public Base {
public:
    ~Derived() { std::cout << "Derived destructor" << std::endl; }
};

// 自定义删除器
struct ArrayDeleter {
    template <typename T>
    void operator()(T* ptr) const {
        delete[] ptr;
    }
};

int main() {
    // 使用自定义删除器的std::unique_ptr管理多态对象数组
    std::unique_ptr<Base, ArrayDeleter> arr(new Derived[3]);

    return 0;
}

在上述代码中:

  • 定义了基类Base和派生类Derived,都有虚析构函数。
  • 定义了一个自定义删除器ArrayDeleter,它使用delete[]来释放对象。
  • main函数中,使用std::unique_ptr<Base, ArrayDeleter>来管理Derived对象数组,这样在std::unique_ptr析构时,会调用自定义删除器正确释放数组内存。