如何使用boost :: call_once在Linux上用C ++设计单例类?

时间:2012-05-27 21:47:55

标签: c++ linux multithreading boost singleton

我正在使用boost::call_once在Linux上用C ++设计一个线程安全的单例类。

我收到了以下编译错误:

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

3 个答案:

答案 0 :(得分:4)

错误表明boost :: call_once不能处理成员函数指针。这是因为你忘了让makeInstance和getInstance都是静态的。

答案 1 :(得分:2)

为什么要写一个析构函数?您打算销毁哪个实例?哦,等等,只有一个,因为它是一个单例,所以在这种情况下为什么析构函数会尝试删除实例?无限递归失败。

无论如何,单身人士闻到了,避免它们。

答案 2 :(得分:1)

由于AardvarkSoup(美味营养)指出,您需要makeInstance()getInstance()是静态的。

此外,您需要定义SingleTon(),而不仅仅是声明它,因为它已在makeInstance()中使用。

最后,您需要初始化静态成员p,例如:

SingleTon* SingleTon::p(nullptr);

这使代码编译。但是,设计一个线程安全的单例类并非易事。请参阅this question,了解有关为什么要尝试避免使用单身人士的完整解释的链接。