"Fast Pimpl" Idiom in <<Exceptional C++>>?

"Fast Pimpl" Idiom in <<Exceptional C++>>?

Post by john » Tue, 17 Dec 2002 19:34:48



In P115, Item30 -- The "Fast Pimpl" Idiom, it changes from a template
class to another class, that is, change from:

template<size_t S>
class FixedAllocator
{
public:
   void* Allocate(/*requested size is always S*/);
   void  Deallocate(void*);
private:
   /*implemented using statics? ... */

Quote:};

to:

class FixedAllocator
{
public:
   static FixedAllocator& Instance();
   void*  Allocate(size_t);
   void   Deallocate(void*);
private:
   ...

Quote:};

why is there the need of such a change? P115 said that "Because the
private details (of the templated class) are liked to use statics,
there could be problems if Deallocate is ever called from a static
object's destructor."

I can't quite understand these words. What problem shall we meet if
Deallocate is called from a static object's destructor? Any example
for this?


      [ about comp.lang.c++.moderated. First time posters: do this! ]

 
 
 

"Fast Pimpl" Idiom in <<Exceptional C++>>?

Post by Philippe Mor » Wed, 18 Dec 2002 06:46:14


Essentially, say that you have a class for which you want to create a static
instance and that object uses FixedAllocator<Size>, you want to be sure that
any structure created by the allocator is created before your class is
created and destroyed after your class is destroyed.

Since the order of initialization of static object in different translation
units is not defined, you want to be sure to force the proper order.

Using a function that returns a static object declared inside that function
will cause the static object to be constructed when the function is called.
Any static object will be destroyed in the reverse order (i.e. first created
will be last destroyed).

Thus in the book example, if you declare a global (or a static) variable
like this (at global scope - i.e. not inside a function):

    FastArenaObject AGlobalObject;

the function Fixed::Allocator will be called. This function will typically
returns a static object created the first time the function is called. A
simple implementation could be:

    template <size_t S> static FixedAllocator<S> &
FixedAllocator<S>::Instance() {
        static FixedAllocator<S> TheStaticAllocator;
        return TheStaticAllocator;
    }

Doing it that way ensure that A GlobalObject is (fully) created after
TheStaticAllocator and destroyed before it.

In pratice, it would also be possible to make Instance() private and called
it from inside Allocate and Deallocate implementation. It won't affect much
the code except that the call to Instance() would be done inside of
FixedAllocator member functions instead of FastArenaObject one's.


      [ about comp.lang.c++.moderated. First time posters: do this! ]

 
 
 

"Fast Pimpl" Idiom in <<Exceptional C++>>?

Post by john » Thu, 19 Dec 2002 23:22:06


Hi, Mori:
Thanks for your response. Yet, I still can't get it.
would you explain it in a simpler way?

thanks,


      [ about comp.lang.c++.moderated. First time posters: do this! ]

 
 
 

"Fast Pimpl" Idiom in <<Exceptional C++>>?

Post by Philippe Mor » Fri, 20 Dec 2002 09:20:56


Say that in file a.cpp you have:

    class A { };
    static A a;

and in file b.cpp

    class B { };
    static B b;

Since static object a and b are not in the same translation unit, a or b
could be initialized first. This is not defined by the standard and is
implementation-dependant (it will probably done in the order that files
are
passed to the linker).

Then if the constructor of B depend on static a object being already
created, you have a problem. One solution would be to put everything in
the
same file (then initialization order is essentially declaration order of
static and global object).

One way to avoid the problem and ensure that a is created first is to
add a
function like that:

    A &Instance() {
        static A a2;
        return a2;
    }

and then call that function from B constructor instead of a direct
access to
static a object. When the function is called for the first time, the
static
object will be created.

Thus if you define your own memory allocator, that allocator may be used
for
static object initialization. In such a case, you want to be sure that
static data for the allocator is initialized before it is used by the
other
object.

As long as the are no circulary reference (and no threading issues),
that
solution will works fine... It will also require proper destruction
order
which will be typically the case but not always... For example if the
program do have singleton, it may be possible that some object will be
destroyed afterwards...


      [ about comp.lang.c++.moderated. First time posters: do this! ]

 
 
 

1. "Fast Pimpl" Idiom in <<Exceptional C++>>?

In P115, Item30 -- The "Fast Pimpl" Idiom, it changes from a template
class to another class, that is, change from:

template<size_t S>
class FixedAllocator
{
public:
   void* Allocate(/*requested size is always S*/);
   void  Deallocate(void*);
private:
   /*implemented using statics? ... */

to:

class FixedAllocator
{
public:
   static FixedAllocator& Instance();
   void*  Allocate(size_t);
   void   Deallocate(void*);
private:
   ...

why is there the need of such a change? P115 said that "Because the
private details (of the templated class) are liked to use statics,
there could be problems if Deallocate is ever called from a static
object's destructor."

I can't quite understand these words. What problem shall we meet if
Deallocate is called from a static object's destructor? Any example
for this?

thanks,

2. HP 2100 * W2K -- Does configuration utility work?

3. HELP >>>>>>>>>>>>> WINAPI <<<<<<<<<<<<<<<<<

4. FS:Sun 4.3 - 2.1 Gig Hard Drives.

5. >>>>>>>>> PROBLEM WITH MSICPB.EXE <<<<<<<<<<<<<<<<<

6. MTS

7. <<<<<<Programmers Needed>>>>>>>

8. UML Example

9. <<>><><><><><><><><><><>

10. <><><> www.FotoCD.net <><><>

11. ************************<<<<<<LOTUS CORP.SUCKS>>>>>*****************

12. >>>>>STUCK<<<<<< How to subclass desktop?