Skip to content

無 Heap 的 Pimpl ​

Ref: Type-safe Pimpl implementation without overhead

一般 Pimpl 用 std::unique_ptr<Impl>,每個物件都要多一次 heap allocation。

改法:在 header 先給定 Impl 的大小與對齊,物件內放一塊 buffer,建構時用 placement new 把 Impl 建在 buffer 上。

cpp
// foo.h
class Foo {
public:
    Foo();
    ~Foo();
private:
    struct Impl;
    alignas(8) std::byte storage_[64];  // 需 >= sizeof(Impl)
    Impl& impl();
};

// foo.cpp
struct Foo::Impl { /* ... */ };

Foo::Foo() {
    static_assert(sizeof(Impl) <= sizeof(storage_));
    static_assert(alignof(Impl) <= 8);
    new (storage_) Impl();
}
Foo::~Foo() { impl().~Impl(); }
Foo::Impl& Foo::impl() { return *std::launder(reinterpret_cast<Impl*>(storage_)); }
  • 缺點:Impl 變大就要改 header,失去部分 Pimpl 隔離編譯的好處。
  • 大小或許可以交給 CMake 在建置時預先算好再產生 header。

頁面歷史

Just observe 👀