I'm new to programing and I was trying for the program which makes the class singleton..Is this the correct approach for making a class singleton??
#include <iostream>
using namespace std;
class Singleton
{
private:
static bool instanceFlag;
static Singleton *single;
public:
static Singleton* getInstance();
void method();
~Singleton()
{
instanceFlag = false;
}
};
bool Singleton::instanceFlag = false;
Singleton* Singleton::single = NULL;
Singleton* Singleton::getInstance()
{
if(! instanceFlag)
{
single = new Singleton();
instanceFlag = true;
return single;
}
else
{
return single;
}
}
void Singleton::method()
{
cout << "Method of the singleton class";
}
int main()
{
Singleton *sc1,*sc2;
sc1 = Singleton::getInstance();
sc1->method();
sc2=Singleton::getInstance();
sc2->method();
return 0;
}
Is this the correct way of making class singleton??
You are over-complicating things. Try the Scott Meyers singleton:
struct SingletonClass {
// instance() function return a reference
static SingletonClass& instance() {
// static local variable are initialized one time.
static SingletonClass inst;
// We return the instance, which is the same for every calls.
return inst;
}
private:
// Private since we don't want other class to create instances
SingletonClass() = default;
// Our class is not copiable or movable
SingletonClass(const SingletonClass&) = delete;
SingletonClass(SingletonClass&&) = delete;
SingletonClass& operator=(const SingletonClass&) = delete;
SingletonClass& operator=(SingletonClass&&) = delete;
};
You can use your class like that:
auto& myInstance = SingletonClass::instance();
Bonus: It doesn't use dynamic allocation, it's thread safe, and is much simpler.
try this solution:
class Singleton {
private:
static Singleton* instance;
Singleton() {} // must be private
public:
static Singleton* getInstance() {
if (instance == NULL)
instance = new Singleton();
return instance;
}
void method() { cout << "Method of the singleton class\n"; }
};
Singleton* Singleton::instance = NULL;
Related
Is it possible to define a Meyer's singleton (like this one) with arguments?
I know it is possible with the GOF style singleton (like here),
but I can't seem to make it work with Meyer's singletons:
// ...
public:
static S& getInstance()
{
static S instance; // no way to pass arguments here ...
return instance;
}
EDIT:
I want a single Init function, and multiple getInstance.
So a typical usage is something like:
S::Init(5, 6.4);
foo(S::getInstance());
bar(S::getInstance());
You can just store the initialization parameters in statics. Example:
class S {
public:
static void Init(int i)
{
i_ = i;
initialized_ = true;
}
static S& getInstance()
{
if (!initialized_) {
throw SomeException;
}
static S instance(i_);
return instance;
}
private:
S(int) { }
static int i_;
static bool initialized_;
};
Remember to actually define the statics in the implementation (.cpp) file:
int S::i_ = 0;
bool S::initialized_ = false;
Obviously you could use Meyer singletons as well for these, but since they're built-in types and do not depend on other data, you wouldn't really gain much.
You could do something like this:
class Singleton
{
private:
static std::unique_ptr<Singleton>& getObject()
{
static std::unique_ptr<Singleton> instance;
return instance;
}
Singleton(int foo);
public:
static void Init(int foo)
{
auto& instance = getObject();
if (instance) throw std::runtime_error("aleady inited");
instance.reset(new Singleton(foo));
}
static Singleton& getInstance()
{
auto& instance = getObject();
if (!instance) throw std::runtime_error("not inited");
return *instance;
}
};
Note that this isn't thread safe and will have undefined behaviour if multiple threads call Init or a thread calls getInstance whilst another is calling Init.
If your parameters could be replaced by template arguments then you could do it this way instead:
template <int foo>
class SingletonImpl
{
private:
SingletonImpl(int f);
public:
static SingletonImpl<foo>& getInstance()
{
static SingletonImpl<foo> instance(foo);
return instance;
}
};
using Singleton = SingletonImpl<10>;
The best solution is probably to separate initialisation and construction:
class Singleton
{
private:
std::atomic<bool> initialised;
Singleton()
: initialised(false)
{
}
Singleton& instanceImpl()
{
static Singleton singleton;
return singleton;
}
public:
void Init(int foo)
{
auto& instance = instanceImpl();
if (instance.initialised) throw std::runtime_error("already inited");
instance.initialised = true;
}
Singleton& getInstance()
{
auto& instance = instanceImpl();
if (!instance.initialised) throw std::runtime_error("not inited");
return instance;
}
};
I see errors like
src/singleton.cxx:16:error: invalid use of member 'Singleton::instance' in static member function
src/singleton.cxx:28:error: from this location
src/singleton.cxx:16:error: invalid use of member 'Singleton::instance' in static member function
src/singleton.cxx:29:error: from this location
src/singleton.cxx:16:error: invalid use of member 'Singleton::instance' in static member function
src/singleton.cxx:31:error: from this location
src/singleton.cxx: In function 'int main()':
Now after making changes I get the following errors
singleton-rhel6.3.o: In function Singleton::get_instance()':
src/singleton.cxx:27: undefined reference toSingleton::instance'
#include <cstddef>
class Singleton {
private:
Singleton();
static Singleton * instance;
int m_num;
int incr_call();
public :
static Singleton * get_instance();
};
Singleton * Singleton::get_instance() {
if(instance == NULL)
instance = new Singleton();
return instance;
}
Singleton::Singleton():
m_num(0)
{
}
int Singleton::incr_call() {
return m_num++;
}
int main() {
Singleton * s = Singleton::get_instance();
return 0;
}
instance should be static since you want to be able to call it in get_instance. Also, instance should be private:
class Singleton {
public :
static Singleton * get_instance();
private:
Singleton();
static Singleton * instance;
int m_num;
int incr_call();
};
Singleton* Singleton::instance;
You should change your constructor too, to not initialize instance:
Singleton::Singleton():
m_num(0)
{ }
Because instance is static default initialization is done and it will be NULL / nullptr.
If you have to use singleton, use Meyers' one:
class Singleton {
private:
Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
public :
static Singleton& get_instance()
{
static Singleton instance;
return instance;
}
// Extra stuff
};
I have recently started working on a very old project and from the beginning of the project design pattern was not properly used. Now in one situation I want to make an already existing class a singleton class. In most tutorials I have seen that singleton classes uses a method to return object reference, like getInstance() in the following. Problem is everywhere in the project object is declared without help of any method except constructor. Is there any way to modify existing class so that without changing object creation method i can implement singleton pattern?
class Singleton
{
private:
static bool instanceFlag;
static Singleton *single;
Singleton()
{
//private constructor
}
public:
static Singleton* getInstance();
void method();
~Singleton()
{
instanceFlag = false;
}
};
bool Singleton::instanceFlag = false;
Singleton* Singleton::single = NULL;
Singleton* Singleton::getInstance()
{
if(! instanceFlag)
{
single = new Singleton();
instanceFlag = true;
return single;
}
else
{
return single;
}
}
void Singleton::method()
{
cout << "Method of the singleton class" << endl;
}
int main()
{
Singleton *sc1,*sc2;
sc1 = Singleton::getInstance();
sc1->method();
sc2 = Singleton::getInstance();
sc2->method();
return 0;
}
You can use the Pimpl idiom to do that, but remember, singletron are a bad design patterns, once you are dealing, in fact, with global variables.
Below is a simple program showing how you can do that. Note that I'm to dealing with single life time, just showing the concept:
#include <iostream>
using namespace std;
class SingletonImpl
{
public:
void method() {
cout << "Method of the singleton class" << endl;
}
};
class Singleton
{
private:
static bool instanceFlag;
static SingletonImpl *single;
public:
Singleton()
{
if ( !instanceFlag ) {
single = new SingletonImpl();
instanceFlag = true;
}
}
void method();
~Singleton()
{
// Do your life time management here
}
};
bool Singleton::instanceFlag = false;
SingletonImpl* Singleton::single = NULL;
void Singleton::method()
{
single->method();
}
int main()
{
Singleton *sc1,*sc2;
sc1 = new Singleton();
sc1->method();
sc2 = new Singleton();
sc2->method();
return 0;
}
I have implemented Singleton class method hpp and cpp like the following
Singleton.hpp
class Singleton {
private:
Singleton();
public:
virtual ~Singleton();
static Singleton &instance();
int getMemberField();
void setMemberField(int mf);
private:
static Singleton *p_instance;
int m_memberField;
};
Singleton.cpp
Singleton* Singleton::p_instance=NULL ;
Singleton::Singleton() {
p_instance = this;
m_memberField = 0;
}
Singleton::~Singleton() {
p_instance = NULL;
}
Singleton& Singleton::instance() {
if (p_instance==NULL) {
p_instance = new Singleton();
}
return *p_instance;
}
int Singleton::getMemberField(){
return m_memberField;
}
void Singleton::setMemberField(int mf){
m_memberField = mf;
}
My problem is how to access those methods either set or get in application classes.
Please help,
Singleton::instance().setMemberField(42);
Suppose we have to use a single object of a class throughout the lifetime of an application. In BlackBerry 10, is it possible to declare a global object, which can be used anywhere inside the program?
You could do that, but a better way may be to use a class designed to be a singleton:
Singleton.hpp
class Singleton {
private:
Singleton();
public:
virtual ~Singleton();
static Singleton &instance();
int getMemberField() { return m_memberField; }
void setMemberField(int mf) { m_memberField = mf; }
private:
static Singleton *p_instance;
int m_memberField;
};
Singleton.cpp
Singleton* Singleton::p_instance = NULL;
Singleton::Singleton() {
p_instance = this;
m_memberField = 0;
}
Singleton::~Singleton() {
p_instance = NULL;
}
Singleton& Singleton::instance() {
if (p_instance == NULL) {
p_instance = new Singleton();
}
return *p_instance;
}
In application code
Singleton::instance().setMemberField(25);
Singleton::instance().getMemberField();
The real benifit of this is that the singleton looks after its own global pointer.