Search code examples
c++boostshared-ptr

Using a static initializer function


In this contrived example, I have a static initialization function that is run at construction time.

I'd like to know if this a legal way to initialize a_, b_, and c_. Or, is it too early in the construction process to use them this way?

DWORD SomeInitializationFunction( HANDLE*, DWORD*, DWORD* );

class MyClass
{
public:
    MyClass() : m_( MyClass::Create( &a_, &b_, &c_ ), &::CloseHandle )
    {
    };

private:

    static HANDLE Create( DWORD* a, DWORD* b, DWORD* c )
    {
        DWORD a1, b1;
        HANDLE h;

        *c = ::SomeInitializationFunction( &h, &a1, &b1 );
        if( *c == 0 )
        {
            *a = a1;
            *b = b1;
            return h;
        }
        return NULL;
    };

    boost::shared_ptr< void > m_;
    DWORD a_;
    DWORD b_;
    DWORD c_;
};

Thanks, PaulH


Solution

  • Members in a class are initialized in the order they are defined in the class. Thus if you have

    class A
        int t
        int u
        int v
    A() : v(0), u(1), t(2) {}
    

    Then despite the order in which you write the constructor arguments, first the value of t would be set, then the value of u and finally the value of v.

    So if you change the order of definition of your class to:

    class MyClass
    {
    public:
        MyClass() : m_( MyClass::Create( &a_, &b_, &c_ ), &::CloseHandle )
        {
        };
    
    private:
    
        static HANDLE Create( DWORD* a, DWORD* b, DWORD* c )
        {
            DWORD a1, b1;
            HANDLE h;
    
            *c = ::SomeInitializationFunction( &h, &a1, &b1 );
            if( *c == 0 )
            {
                *a = a1;
                *b = b1;
                return h;
            }
            return NULL;
        };
    
    
        DWORD a_;
        DWORD b_;
        DWORD c_;
        boost::shared_ptr< void > m_;
    };
    

    then your constructor should be okay.

    I'd suggest putting in a comment saying that there is a dependency in the initialization of the members of your class so that people reading the code would know not to fiddle around.