跳转到内容

更多 C++ 惯用法/快速 Pimpl

来自维基教科书,开放的书籍,开放的世界

提高句柄体惯用法的性能。

也称为

[编辑 | 编辑源代码]

常规 PIMPL 惯用法通过牺牲性能来实现“编译防火墙”。快速 PIMPL 试图通过在原始接口对象中组合实现对象来减少堆分配和非本地内存访问的开销。

解决方案和示例代码

[编辑 | 编辑源代码]
// Wrapper.hpp
struct Wrapper {
    Wrapper();
    ~Wrapper();

    std::aligned_storage_t<32, alignof(std::max_align_t)> storage;
    
    struct Wrapped; // forward declaration
    Wrapped* handle;
};
// Wrapper.cpp
struct Wrapper::Wrapped {
};

Wrapper::Wrapper() {
    static_assert(sizeof(Wrapped) <= sizeof(this->storage) , "Object can't fit into local storage");
    this->handle = new (&this->storage) Wrapped();
}

Wrapper::~Wrapper() {
    handle->~Wrapped();
}

请注意,不需要对 Wrapped 类的实例进行句柄处理。为了减少内存占用,可以通过辅助函数访问 Wrapped 类。

static Wrapper::Wrapped* get_wrapped(Wrapper* wrapper) {
    // c++17 compatible
    return std::launder(reinterpret_cast<Wrapper::Wrapped*>(&wrapper->storage));
}

已知用途

[编辑 | 编辑源代码]

当需要实现不可见或解耦时,这种模式经常用于高性能或内存受限的环境中。

[编辑 | 编辑源代码]

参考文献

[编辑 | 编辑源代码]

快速 Pimpl 惯用法

华夏公益教科书