Reputation: 5040
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
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
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
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