[odb-users] Re: Handling pimpl idiom in ODB

Boris Kolpackov boris at codesynthesis.com
Thu Aug 18 07:12:57 EDT 2011

Hi Uwe,

Uwe Kindler <uwe_kindler at web.de> writes:

> I think your first approach, making only the 'impl' class an ODB object  
> will not work. Because then I cannot use the public interface class in a  
> relation because ODB does not know anything about the interface class.
> That means I cannot have another persistent class that has a one to many  
> or one to one relation to my COdbPimplTest interface class.

Yes, I missed that. This is another pretty big limitation of the first

> When I first thought about this problem, I tried to solve it with a  
> composite value type. That means I thought of the private impl class as  
> a composite value type. But it was not possible to use a pointer to a  
> composite value type so I decided to go the persistent object way.

That's actually a pretty good idea. See more on that below.

> Regarding the second approach I have a question. The keyword virtual  
> does not mean, that it will be a virtual method, or does it?

No, virtual in this context simply means that there is no actual C++
data member. 

> The problem with the second approach is, that it would cause a lot of  
> pragmas for the accessors and modifiers. At the moment one big plus for  
> ODB is that I can make a class persistent with a minimum number of 
> changes:
> Often
> #pragma db object
> #pragma db id auto
> friend class odb::access;
> are the only thing you need to make a class persistent. An then I would  
> need to write a pragma for each member. This won't make the more  
> beautiful ;O). But if it works, I think it would be o.k.

Yes, that's the drawback. However, it kind of parallels the extra work
you have to do when you use the pimpl idiom, such as forwarding the
calls to the 'impl' class. In essence, the virtual member pragma is
'forwarding' of the data member to the one in 'impl' class. Note
also that the pragmas can always be moved out of the class or even
into a separate file.

Plus, as I will discuss in more detail below, this approach is the
most flexible.

> What do you think about the composite value approach. Would it be  
> possible to implement pointers to composite values?

Yes, I think it would. For the upcoming release of ODB, we have
implemented the concept of wrappers. In ODB, wrapper is essentially
a type that wraps a value type. The primary purpose of wrappers is
to add the NULL semantics to types that otherwise don't have it.
However, wrappers don't have to handle NULL (such wrappers are
called transparent). Some examples of wrappers include smart
pointers and optional value containers, such as boost::optional.

Now, currently, wrappers are only supported for simple values
because at the moment we only support the NULL semantics for
simple values. However, there are plans to extend the NULL
support to composite values and maybe even containers. So the
idea is that wrappers should work equally well for both simple
and composite values. I can now see how a transparent wrapper
for a composite value can be very useful when implementing the
pimpl idiom.

There are a couple of limitations to this approach, however:

1. The id member will have to be defined in the 'interface'
   class instead of the 'impl' class. This is probably not
   a big issue since presumably this member doesn't get 
   added/deleted/changed very often. Note that the virtual
   member approach doesn't have this limitation.

2. Organizationally, you will need to have a separate header
   that contains the 'impl' value definition. Normally, the
   'impl' class is defined in the source file. Again, the
   virtual member approach doesn't have this limitation.

3. Whenever you need to perform a database operation, the
   definition of the 'impl' value type will have to be visible.
   In other words, whenever you #include the -odb.hxx file
   corresponding to the object, the definition of the value
   type will be included as well. I am not sure if this is
   an issue in your case. Again, the virtual member approach
   doesn't have this limitation.

Would you like to give the value type approach a try? If so,
I can add support for transparent wrappers for composite values
and build you a pre-release binary. Just let me know for which
platform you need the ODB compiler binary, if any.


More information about the odb-users mailing list