top | item 37016947

(no title)

BenFrantzDale | 2 years ago

I’m curious: do you use a `const std::unique_ptr<Impl>` or just a `std::unique_ptr<T>` or do you have a template that provides value semantics for the `Impl`? If I used PImpl a lot I’d make a `value<T>` that encapsulates ownership with value semantics.

discuss

order

BenFrantzDale|2 years ago

And conversely, if you are using classical polymorphism, you can get essentially the effect of PImpl by having an abstract base class with a static factory function that returns a unique pointer, then implement that factory function by in the cpp file having a concrete class that is defined there and returned as a `std::unique_ptr<IBase>`. That gives you separation of API from implementation without a memory indirection, but you then can’t have it as a value type.

rewmie|2 years ago

> if you are using classical polymorphism, you can get essentially the effect of PImpl (...)

No, not really. That's only an option for the rare cases where you control the whole class and all it's members, and you can break any ABI whenever you like by converting any class to a protocol class.

In the real world, pimpls are applied to member variables that were encapsulated in the past but you want to remove their definition from the interface, or classes that are generated with code generators at compile time. It makes little sense to replace a class with a protocol+implementation+factory just because you want to get rid of a member variable or you need to consume a auto-generated class.