-1

マルチスレッド環境でラッパー内にシングルトン クラスのインスタンスを作成しようとしています。私はラッパーを使用して作業を楽にし、複数回 Lock と Unlock を ManagerSources に書き込まないようにしています。

#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

構文が機能せず、「'GetInstance' の定義または再宣言は関数内では許可されていません」というエラーが表示されます。そして、理由はわかりません。これを解決する方法についてのアイデアはありますか?

また、私にとって奇妙な事実は、コンストラクターをデフォルトのパラメーターで次のように書き換えた場合です。

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パラメータを取らず、 type を返す関数の宣言として解釈されます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 に答える