Question

I'm having some trouble converting a working pimpl class to singleton. Here is the starting code:

apirequest.h

class ApiRequestPrivate;

class ApiRequest
{
public:

    ApiRequest( int );
    ~ApiRequest( );

    int method1();

private:
    ApiRequestPrivate* const d;
};

apirequest_p.h

#include "apirequest.h"

class ApiRequestPrivate
{
public:
    ApiRequestPrivate( int );

    int method1();

private:
    int member1;
};

apirequest.cpp

#include "apirequest.h"
#include "apirequest_p.h"

ApiRequestPrivate::ApiRequestPrivate( int value )
{
    member1 = value;
}

int ApiRequestPrivate::method1( )
{
    return member1;
}

ApiRequest::ApiRequest( int value ) : d( new ApiRequestPrivate( value ) )
{
}

ApiRequest::~ApiRequest()
{
    delete d;
}

int ApiRequest::method1( )
{
    return d->method1( );
}

First, I did the following modifications:

apirequest.h

class ApiRequest
{
public:
    ~ApiRequest( );

    static ApiRequest * getApiRequest(int);

    int method1();

private:
    ApiRequestPrivate* const d;
    ApiRequest( int );
};

apirequest_p.h

class ApiRequestPrivate
{
public:
    ...
    static ApiRequest * getApiRequest(int);

private:
    ...
    static ApiRequest * m_apiRequest;
};

apirequest.cpp

...

ApiRequest * ApiRequestPrivate::getApiRequest( int value )
{
    if(m_apiRequest == 0) {
        m_apiRequest = new ApiRequest( value );
    }

    return m_apiRequest;
}

...

ApiRequest * ApiRequest::getApiRequest( int value )
{
    return d->getApiRequest( value );
}

but compilation fail with various errors, the first of which is:

In file included from apirequest.cpp:1:0:
apirequest.h: In static member function ‘static ApiRequest* ApiRequestPrivate::getApiRequest(int)’:
apirequest.h:17:5: error: ‘ApiRequest::ApiRequest(int)’ is private
     ApiRequest( int );
     ^
apirequest.cpp:17:46: error: within this context
         m_apiRequest = new ApiRequest( value );
                                              ^

Then I tryed moving ApiRequest() constructor back to public and compilation fails with the following code:

In file included from apirequest.cpp:1:0:
apirequest.h: In static member function ‘static ApiRequest* ApiRequest::getApiRequest(int)’:
apirequest.h:17:30: error: invalid use of member ‘ApiRequest::d’ in static member function
     ApiRequestPrivate* const d;
                              ^
apirequest.cpp:39:12: error: from this location
     return d->getApiRequest( value );
            ^

Do you have any tip on this task? Very thanks

Was it helpful?

Solution

The first is because you're trying to create ApiRequest using a private constructor from another class, ApiRequestPrivate. Presumably, the constructor wants to be private to support whatever singleton-based insanity you think you want; so one solution is to make ApiRequestPrivate a friend of ApiRequest.

Alternatively, you could create the object in ApiRequest::getApiRequest. There's no point moving the implementation of that function into the private class.

The second is because the function is static, so there is no object to access the members of. However, the function you're calling is also static, so you don't need the object anyway:

return ApiRequestPrivate::getApiRequest(value);

But, again, there's really no point introducing that extra function.

I'm also wondering what's supposed to happen if you want to pass one value to the function to create the request, and then pass a different value the next time. If that needs to change, then a singleton is probably an even worse idea than it usually is.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top