user1002288
user1002288

Reputation: 5040

How to design a singleton class in C++ on Linux using boost::call_once?

I am designing a thread-safe singleton class in C++ on Linux using boost::call_once.

I got the following compiler error:

/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

After seeing some posts, I still do not know how to handle this error. How do I change the void (SingleTon::)() to 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;
}

Upvotes: 1

Views: 2907

Answers (3)

Jonathan Wakely
Jonathan Wakely

Reputation: 171383

Why have you written a destructor? Which instance do you plan to destroy? Oh wait, there's only one, cos it's a singleton, so in that case why does the destructor try to delete the instance? Infinitely recursive failure.

Singletons smell anyway, avoid them.

Upvotes: 2

Fraser
Fraser

Reputation: 78398

As AardvarkSoup (tasty and nutritious) pointed out, you need makeInstance() and getInstance() to be static.

Also, you need to define SingleTon(), not just declare it, since it's used in makeInstance().

Finally, you need to initialise the static member p, like:

SingleTon* SingleTon::p(nullptr);

This makes the code compile. However, designing a thread-safe singleton class is non-trivial. See this question for piles of links to very full explanations as to why you should try and avoid using singletons.

Upvotes: 1

AardvarkSoup
AardvarkSoup

Reputation: 1081

The error indicates boost::call_once doesn't work on member function pointers. This is because you forgot to make both makeInstance and getInstance static.

Upvotes: 4

Related Questions