
Hi! Recently there was a proposal to add a class template that simplifies the implementation of a PIMPL idiom to Boost. Unfortunately I missed the review deadline so I could not submit a proper review. But I do have some experience with PIMPL class template that I would like to share with you. I wrote similar class template a couple of years ago (see attached file). The basic idea is the same as in a proposed PIMPL class. I call it ImplWrapper, because it is used to wrap class implementation details. Besides automating the standard PIMPL functionality, it also addresses the following issues: 1. The Impl object can be allocated in a buffer that is provided by ImplWrapper class. The reason for this is to avoid unnecessary allocation of small objects on the heap and to increase performance. In fact, I believe that with proper compiler optimizations, there should be no difference between using ImplWrapper class and storing data members in class directly (additional pointer indirection normally associated with a PIMPL idiom is eliminated). The drawback is that the size of the Impl object must be known (guessed) in advance. Sometimes this is not possible, so there is also alternative implementation that allocates Impl object on the heap. 2. Arbitrary parameters can be passed to Impl constructor by wrapping them in a temporary struct. This struct Par, is forward declared within ImplWrapper class and can be specialized for each type of Impl class. There is no need for policies or other design complications. 3. Simplicity. The overall design seems simple, yet functional. But I do admit that this opinion may by biased. ;-) Since the above issues were not resolved within the proposed PIMPL class (I only quickly glanced over the implementation and a PIMPL thread in this list at the end of May, so I might have skipped something), I decided to post my implementation here. I believe that PIMPL idiom is so often used in C++, that it should have some support in Boost (maybe even in future versions of standard C++ library). Hopefully this post will contribute to that goal. Any comments are greatly appreciated. Regards, Aljaz

For pimpl, I personally use boost::shared_ptr. Sure it has the "overhead" of the control block, but since how you implement pimpl is (duh!) an implementation detail, shared_ptr is perfect for a default implementation. So if I need to, I can simply convert it to a raw pointer later. But consider that the object the shared_ptr points to is usually rather complex, and therefore the additional space requirements to store the shared_ptr control block are unlikely to cause problems. --Emil

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Emil Dotchevski Sent: Thursday, July 27, 2006 2:37 AM To: boost@lists.boost.org Subject: Re: [boost] pimpl pointer revisited
For pimpl, I personally use boost::shared_ptr. Sure it has the "overhead" of the control block, but since how you implement pimpl is (duh!) an implementation detail, shared_ptr is perfect for a default implementation. So if I need to, I can simply convert it to a raw pointer later. But consider that the object the shared_ptr points to is usually rather complex, and therefore the additional space requirements to store the shared_ptr control block are unlikely to cause problems.
True. But there are also small implementation details that may be beneficial to hide. A typical example that I have come across most often, is a handle to some system resource to which the class is a wrapper. Since a system handle is a small object, allocating it on the heap may not be the most efficient way of doing things. Consequently, many developers abandon the PIMPL idiom altogether and place the handle object in class as a member. This results in a dependency on otherwise unnecessary system includes for all users of the class. Aljaz
participants (2)
-
Aljaz Noe
-
Emil Dotchevski