4 ms·
Pimpl seems to me like a workaround for deficiencies in the language. It's verbose and inconvenient. We should be able to add private member functions to a clas
by colonwqbang 5y ago
Pimpl seems to me like a workaround for deficiencies in the language. It's verbose and inconvenient. We should be able to add private member functions to a class without having to recompile all files that use the class. We should be able to forward-declare a class including public member functions without also declaring the member variables of the class.
Even in C I can say:
struct A;
void public_member_function(A *a);
I can also add as many static functions as I like later without affecting the public declararation of struct A.
Why not in C++?
- zozbot234 5y agoPIMPL is not a workaround for language-level deficiencies, it's a workaround/pattern for ensuring a forward-compatible ABI.
- ncmncm 5y agoYou may do that in C++, too. It would look, literally, exactly the same. It would compile, and run, identically. And, it would be exactly as error-prone as the same code compiled with a C compiler. Extra support in the language for automating PImpl types could be welcome, but might not offer enough benefit to offset the complexity.
- colonwqbang 5y agoWhy do you feel that it's more error-prone? function(a); vs. a->function(); I can accept that some think the second version looks nicer. But I don't buy that we should have to jump through hoops like pimpl just to get there for non virtual calls.
- ncmncm 5y agoNobody cares how it looks. What matters is that your "a" is a naked pointer. Pointers have reference semantics, not value semantics, so are inherently error-prone. A pointer might be null. A pointer might be already freed. A pointer might be left over from some other use. A PImpl object is a value, with value semantics. It owns the wrapped pointer, and whatever that points at. When it goes out of scope, it cleans up. If you throw, it cleans up. When it is copied, the right thing happens, if that is allowed, or cannot happen, if not. When it is passed to a function, the right thing happens. When it is returned from a function, the right thing happens. The "right thing", in each case, is visible in exactly one place in the source code, and nowhere else. Nothing using it can do any of it wrong. This is all really fundamental stuff.