1

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;
}
Fraser
  • 74,704
  • 20
  • 238
  • 215
user1002288
  • 4,860
  • 10
  • 50
  • 78

3 Answers3

4

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.

AardvarkSoup
  • 1,071
  • 8
  • 18
  • I have updated the code and still have errors for adding some code to do test in main(), any help is apprciated. thanks ! – user1002288 May 27 '12 at 22:47
2

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.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
1

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.

Community
  • 1
  • 1
Fraser
  • 74,704
  • 20
  • 238
  • 215