函数内部不允许定义或重新声明“GetInstance”

时间:2012-08-21 13:38:35

标签: c++ templates constructor thread-safety singleton

我试图在多线程环境中的包装器内创建一个单例类的实例。我正在使用包装器来简化我的工作,而不是在ManagerSources中多次写入Lock和Unlock。

#define ManagerSOURCES() ManagerSources::GetInstance()

// Singleton
class ManagerSources :public Mutex {

protected:

    std::map< std::string , SourcesSPtr > Objects;

    static ManagerSources * Instance; // declared in a cpp file
    ManagerSources() {}
    ManagerSources( const ManagerSources& cpy ) {}
    ManagerSources operator=( ManagerSources& cpy) {}

public:

    static ManagerSources* GetInstance() {
        if ( Instance == NULL )
            Instance = new ManagerSources();
        return Instance;
    }

    ...
};

// This class is a wrapper for ManagerSources in a thread programming environment
template <class T>
class SingletonThreadSafe {

protected:

    T *pointer;

public:

    class proxy {
        T* pointer;

    public:

        proxy(T* _pointer) : pointer(_pointer) {
            // LOCK();            
        }

        ~proxy(){
            // UNLOCK();
        }

        T* operator->() {
            return pointer;

        }
    };


    // Default parameter is needed for containers (eg. insert into a map) where we need
    // a constructor without parameters
    SingletonThreadSafe(T* cpy = NULL ): pointer(cpy) {

    }

    ~SingletonThreadSafe() {
    }

    SingletonThreadSafe(const SingletonThreadSafe & cpy) {

        this->pointer = cpy.pointer;

    }

    SingletonThreadSafe operator=(SingletonThreadSafe cpy) {

            this->pointer = cpy.pointer;

            return *this;

    }

    T operator*() {

        return *pointer;

    }

    proxy operator->() {

        return proxy( pointer );

    }
};

我有以下声明

typedef SingletonThreadSafe<ManagerSources> aa;

aa( ManagerSources::GetInstance() ); // doesn't work

or 

aa( ManagerSOURCES() ); // the same as above; still not working

语法不起作用,它给我以下错误&#34;定义或重新声明&#39; GetInstance&#39;不允许进入功能&#34; 。而且,我不知道为什么。 关于如何解决此问题的任何想法?

另外,对我来说奇怪的事实是我用

的默认参数重写构造函数
SingletonThreadSafe(T* cpy = T::GetInstace() ): pointer(cpy) {

}

以下声明有效

aa()->A_Function(A_Parameter);

如果我声明它仍然有效

aa bb( ManagerSOURCES() ); //  it works

( SmartPtr<ManagerSources>() = ManagerSOURCES() )->A_Function(A_Parameter); // it works; 
// the constructor with the  default parameter is called 

我不知道为什么会收到错误&#34;定义或重新声明&#39; GetInstance&#39;不允许在函数内部使用&#34;。

我正在使用Xcode 4.4.1和LLVM GCC 4.2编译器。

2 个答案:

答案 0 :(得分:3)

这是最令人烦恼的解析的变体。

aa( ManagerSources::GetInstance() ); // doesn't work

被解释为函数ManagerSources::GetInstance的声明,不带参数并返回类型aa

您可以使用static_cast

解决此问题
static_cast<aa>( ManagerSources::GetInstance() );

转换为void也会起作用,就像阻止表达式被解析为声明的任何其他内容一样:

(void) aa( ManagerSources::GetInstance() );

答案 1 :(得分:2)

aa( ManagerSources::GetInstance() );

这是一个功能声明;相当于:

aa ManagerSources::GetInstance();

如果你想让它创建一个对象,那么要么将它变成一个(命名的)变量声明:

aa x(ManagerSources::GetInstance());

或者,如果您希望它是一个创建临时对象的表达式,那么明确地将它作为表达式:

(void)aa(ManagerSources::GetInstance());

虽然要知道在创建它的完整表达式的末尾会销毁一个未命名的临时文件,这几乎肯定不是你想要的。