将单例功能添加到Pimpl类

时间:2013-10-08 15:53:26

标签: c++ singleton pimpl-idiom

我在将工作的pimpl类转换为单例时遇到了一些麻烦。这是起始代码:

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( );
}

首先,我做了以下修改:

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 );
}

但编译失败并出现各种错误,第一个错误是:

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 );
                                              ^

然后我尝试将ApiRequest()构造函数移回公共,并使用以下代码编译失败:

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 );
            ^

你对这项任务有什么建议吗?非常感谢

1 个答案:

答案 0 :(得分:1)

首先是因为您尝试使用其他类ApiRequest中的私有构造函数创建ApiRequestPrivate。据推测,构造函数想要私有化来支持你认为你想要的任何基于单身的精神错乱;因此,一个解决方案是让ApiRequestPrivate成为ApiRequest的朋友。

或者,您可以在ApiRequest::getApiRequest中创建对象。没有必要将该函数的实现移动到私有类中。

第二个是因为函数是静态的,所以没有对象可以访问成员。但是,您调用的函数也是静态的,因此您无论如何都不需要该对象:

return ApiRequestPrivate::getApiRequest(value);

但是,再一次,引入额外的功能真的没有意义。

我也想知道如果你想将一个值传递给函数来创建请求,然后下次传递一个不同的值,应该会发生什么。如果需要改变,那么单身可能比通常情况下更糟糕。