1

を使用して、Linux 上の C++ でスレッドセーフなシングルトン クラスを設計していますboost::call_once

次のコンパイラ エラーが発生しました。

/tmp/ccLanvZI.o: In function `SingleTon::getInstance()':
singleTon.cpp:(.text._ZN9SingleTon11getInstanceEv[SingleTon::getInstance()]+0x1b): undefined reference to `SingleTon::p'
/tmp/ccLanvZI.o: In function `SingleTon::makeInstance()':
singleTon.cpp:(.text._ZN9SingleTon12makeInstanceEv[SingleTon::makeInstance()]+0x21): undefined reference to `SingleTon::SingleTon()'
singleTon.cpp:(.text._ZN9SingleTon12makeInstanceEv[SingleTon::makeInstance()]+0x2c): undefined reference to `SingleTon::p'
collect2: ld returned 1 exit status
make: *** [singlton] Error 1

いくつかの投稿を見た後でも、このエラーの処理方法がわかりません。void (SingleTon::)()を に変更するにはどうすればよいvoid (*)()ですか?


#include <iostream>
#include <pthread.h>
#include <boost/thread/mutex.hpp>
#include <boost/thread/once.hpp>
#include <boost/bind.hpp>
#include <boost/threadpool.hpp>
#include <boost/thread/thread.hpp>

boost::once_flag flag = BOOST_ONCE_INIT;

class SingleTon
{
    private:
        static SingleTon *p;
        SingleTon();
        SingleTon(const SingleTon&);
        SingleTon& operator=(const SingleTon&);
        void makeInstance();

    public:
        SingleTon* getInstance();

        ~SingleTon()
        {
            if (p)
                delete p;
        }  
};

void SingleTon::makeInstance() 
{
    p = new SingleTon;
    return;
}

SingleTon* SingleTon::getInstance()
{
    boost::call_once( makeInstance  , flag); // error !!!
    return p;
}


int main()
{
    SingleTon *s;
    s = SingleTon::getInstance();
    return 0;
}
4

3 に答える 3

4

このエラーは、boost::call_once がメンバー関数ポインターで機能しないことを示しています。これは、makeInstance と getInstance の両方を静的にするのを忘れたためです。

于 2012-05-27T21:54:06.753 に答える
2

なぜデストラクタを書いたのですか?どのインスタンスを破棄する予定ですか? ちょっと待ってください。シングルトンなので 1 つしかありません。その場合、なぜデストラクタはインスタンスを削除しようとするのでしょうか? 無限に再帰的な失敗。

とにかくシングルトンはにおいがするので、避けてください。

于 2012-05-28T21:32:33.943 に答える
1

AardvarkSoup (美味しく栄養価が高い) が指摘したように、静的である必要がmakeInstance()あります。getInstance()

SingleTon()また、で使用されるため、宣言するだけでなく定義する必要がありますmakeInstance()

p最後に、次のように static member を初期化する必要があります。

SingleTon* SingleTon::p(nullptr);

これにより、コードがコンパイルされます。ただし、スレッドセーフなシングルトン クラスの設計は簡単ではありません。シングルトンの使用を避ける必要がある理由について、非常に完全な説明へのリンクの山については、この質問を参照してください。

于 2012-05-27T23:30:03.840 に答える