MST

星途 面试题库

面试题:C++ std::unique_ptr自定义删除器在复杂资源管理场景下的应用

假设你正在开发一个图形渲染引擎,需要管理一些复杂的图形资源,例如纹理对象。纹理对象的创建和销毁涉及到与底层图形API(如OpenGL)的交互。请使用std::unique_ptr和自定义删除器来实现纹理资源的安全、高效管理。要求考虑多线程环境下的资源竞争问题,并且删除器要能够正确处理不同图形API的资源释放逻辑,同时在代码设计上保持良好的可扩展性和可维护性。
39.8万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#include <memory>
#include <mutex>
#include <iostream>

// 模拟纹理对象
class Texture {
public:
    Texture() { std::cout << "Texture created" << std::endl; }
    ~Texture() { std::cout << "Texture destroyed" << std::endl; }
    // 模拟一些纹理操作函数
    void bind() { std::cout << "Texture bound" << std::endl; }
};

// 自定义删除器基类
class TextureDeleterBase {
public:
    virtual void operator()(Texture* texture) = 0;
    virtual ~TextureDeleterBase() = default;
};

// OpenGL纹理删除器
class OpenGLTextureDeleter : public TextureDeleterBase {
public:
    void operator()(Texture* texture) override {
        // 实际与OpenGL交互释放纹理资源
        std::cout << "Releasing OpenGL texture" << std::endl;
        delete texture;
    }
};

// 其他图形API纹理删除器示例(这里只是示例,可按需扩展)
class OtherAPITextureDeleter : public TextureDeleterBase {
public:
    void operator()(Texture* texture) override {
        // 实际与其他图形API交互释放纹理资源
        std::cout << "Releasing other API texture" << std::endl;
        delete texture;
    }
};

// 线程安全的纹理资源管理类
class TextureManager {
public:
    // 创建纹理资源
    static std::unique_ptr<Texture, TextureDeleterBase> createTexture(const std::string& api) {
        std::unique_lock<std::mutex> lock(mutex_);
        Texture* texture = new Texture();
        if (api == "OpenGL") {
            return std::unique_ptr<Texture, TextureDeleterBase>(texture, new OpenGLTextureDeleter());
        } else {
            return std::unique_ptr<Texture, TextureDeleterBase>(texture, new OtherAPITextureDeleter());
        }
    }

private:
    static std::mutex mutex_;
};

std::mutex TextureManager::mutex_;

int main() {
    // 使用示例
    auto openglTexture = TextureManager::createTexture("OpenGL");
    openglTexture->bind();
    // 离开作用域时,纹理资源会被安全释放

    auto otherAPITexture = TextureManager::createTexture("OtherAPI");
    otherAPITexture->bind();
    // 离开作用域时,纹理资源会被安全释放

    return 0;
}
  1. 自定义删除器
    • 定义了TextureDeleterBase基类,它有一个纯虚的operator()函数用于释放纹理资源。
    • 具体的OpenGLTextureDeleterOtherAPITextureDeleter继承自TextureDeleterBase,分别实现了OpenGL和其他图形API的纹理资源释放逻辑。
  2. 线程安全
    • TextureManager类中,使用std::mutexstd::unique_lock来保证createTexture函数在多线程环境下安全地创建纹理资源,避免资源竞争。
  3. 可扩展性和可维护性
    • 可以通过继承TextureDeleterBase类来轻松添加对其他图形API的支持,例如添加DirectX纹理删除器,只需要创建一个新的继承类并实现operator()函数即可。同时代码结构清晰,便于维护。