-1

我正在尝试在多线程环境中的包装器内创建单例类的实例。我正在使用包装器来简化我的工作,而不是在 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

语法不起作用,它给了我以下错误"Definition or redeclaration of 'GetInstance' not allowed inside a function"。而且,我不知道为什么。关于如何解决这个问题的任何想法?

另外,对我来说奇怪的事实是,如果我用默认参数重写构造函数

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 

我不知道为什么会出现错误“函数内部不允许定义或重新声明 'GetInstance'”。

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

4

2 回答 2

3

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

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

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

您可以使用以下方法解决它static_cast

static_cast<aa>( ManagerSources::GetInstance() );

强制转换void也可以工作,任何其他阻止表达式被解析为声明的东西也可以:

(void) aa( ManagerSources::GetInstance() );
于 2012-08-21T13:49:01.997 回答
2
aa( ManagerSources::GetInstance() );

那是一个函数声明;相当于:

aa ManagerSources::GetInstance();

如果您希望它创建一个对象,则将其设为(命名)变量声明:

aa x(ManagerSources::GetInstance());

或者,如果您希望它成为创建临时对象的表达式,则将其明确设为表达式:

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

尽管请注意,在创建它的完整表达式的末尾会销毁未命名的临时对象,这几乎肯定不是您想要的。

于 2012-08-21T13:52:44.773 回答