views:

78

answers:

2

So I've been thinking about PIMPL and stack allocation. I've been writing a library and decided to use PIMPL to hide the private member of the class. That means I would have a class declared like this

class Foo {
private:
    class Handle;
    std::tr1::shared_ptr<Handle> handle;
public:
    Foo();
};

It's pretty straight forward. But then in the constructor you do this

Foo::Foo() : handle(new Handle()) {}

So when someone using my library creates a Foo on the stack, they are essentially doing a heap allocation anyway. Is this the trade-off you have to live with when using PIMPL? I thought of releasing the documentation with a warning next to constructors: "WARNING: This results in a heap allocation" or somesuch.

My other thought was to have all classes which are exposed to the implementation as pure virtual interfaces and a whole bunch of static factory methods returning smart pointers. This also means heap allocation but there is no trick to it.

Any thoughts or suggestions? Am I being overly-considerate of programmers using my library?

+3  A: 

Is this the trade-off you have to live with when using PIMPL?

Effectively, yes, though there are techniques, such as those discussed by Herb Sutter in "The Fast Pimpl Idiom," that can be used to eliminate or speed up the heap allocation, at the cost of greater complexity.

I thought of releasing the documentation with a warning next to constructors: "WARNING: This results in a heap allocation" or somesuch.

Only if it's necessary to do so (i.e., only if your users would be surprised by the fact that your class performed heap allocation). Many classes perform heap allocation, including many of those in the C++ standard library (all of the containers, for example).

Am I being overly-considerate of programmers using my library?

Possibly :-). Unless you have high performance requirements for your class or you expect instances of your class to be created and destroyed extremely frequently, I wouldn't worry too much about it. Of course, if you do have significant performance requirements, pimpl may not be a good choice.

James McNellis
Cool, thanks. I will look as Fast Pimpl anyway because it looks interesting.
Duracell
+3  A: 

So when someone using my library creates a Foo on the stack, they are essentially doing a heap allocation anyway. Is this the trade-off you have to live with when using PIMPL?

Yep.

I thought of releasing the documentation with a warning next to constructors: "WARNING: This results in a heap allocation" or somesuch.

I'd consider that over aggressive commenting :) If your class is so performance critical, perhaps you should avoid the PIMPL idiom. If you're representing a number, this might be concerning and worth noting. If you're hiding implementation of a database connection, not worth the comment :)

My other thought was to have all classes which are exposed to the implementation as pure virtual interfaces and a whole bunch of static factory methods returning smart pointers. This also means heap allocation but there is no trick to it.

Yeah, it's a little more obvious to the user, but again probably not worth concerning yourself over.

Any thoughts or suggestions? Am I being overly-considerate of programmers using my library?

There's a tradeoff, but if your class is complex enough to really gain from the pimpl idiom, you probably can assume a heap allocation is OK. If I were using your library, it probably wouldn't concern me.

Stephen
Cool, thanks. I'll just keep doin' what I'm doin'.
Duracell