I'm browsing some random code and I found some confusing method, the class is a singleton,
class CFoo
{
CFoo* _instance;
CFoo(){};
public:
~CFoo(){};
static CFoo* getInstance()
{
if(!_instance)
_instance = new CFoo;
return _instance;
}
static void deleteInstance()
{
if(_instance)
delete _instance;
}
// just ordinary member method.
void FooMethod()
{
CFoo::getInstance()->BarMethod(); //confusing..
}
// just ordinary member method.
void BarMethod()
{
//code here..
}
};
CFoo* CFoo::_instance = NULL;
Why FooMethod have to call the CFoo::getInstance() to call the BarMethod? Why not just calling BarMethod() directly?
Please advise.
If you call CFoo::getInstance()->BarMethod() within CFoo::FooMethod(), then the this keyword in the BarMethod refers to CFoo::_instance.
If you call BarMethod() within CFoo::FooMethod(), then the this keyword in the BarMethod refers to the same object on which FooMethod() was called.
It is not entirely clear whether there is effectively any difference. On the one hand, the only constructor that you implemented is private and you refer to the class as a Singleton. This supports the fact that only one instance of CFoo should exist, i.e. this == CFoo::_instance should always hold within BarMethod. On the other hand, CFoo has a public copy constructor, so this == CFoo::_instance might not always be true within BarMethod.
You could call the FooMethod and the Barmethod directly if you could create an object of this class. the problem is you can't do it because the construtor is private. the only way you can create the instance is using the getInstance method. and the method ensure it had no more than single object of this class.
That's why it called singleton.
Related
I know the singleton class does not allow to create more than one object. but as per my below code i can create as many objects as possible.
class Singleton
{
private :
static Singleton *m_Instance;
Singleton()
{
cout<<"In defailt constructor"<<endl;
}
Singleton(int x)
{
i = x;
cout<<"in param const"<<endl;
}
public:
static int i;
static Singleton* createInstance()
{
if(!m_Instance)
m_Instance = new Singleton(20);
Singleton sing;
return m_Instance;
}
};
int Singleton::i=0;
Singleton* Singleton::m_Instance = NULL;
int main()
{
Singleton *pt = Singleton::createInstance();
return 1;
}
Here I am able to create an object in the static function (as i can access constructor within the class) then where is the concept of Single object?
This isn't a singleton for the simple reason that you deliberately wrote something that isn't a singleton.
The idea is that you write the instance function so that it will only create one instance, and write other members so that they don't create any. Then, since they're the only functions that could create any instances, there will only be one.
If you remove the dodgy Singleton sing;, then you'll have a singleton implementation - only one instance will be created, the first time someone calls the function.
As with all attempts to implement this anti-pattern in C++, there are problems: the object is never destroyed, and the initialisation isn't thread-safe. There are various other approaches, each with their own drawbacks. I suggest you avoid global variables altogether, whether or not you dress them up as singletons or other anti-patterns.
The concept of single object comes when in your code, every time you need an instance of your Object, instead of using:
Singleton *myOwnSingleton= new Singleton(20);
You should always use:
Singleton *pt = Singleton::createInstance();
As the constructor is inaccesible outside of the class, the only way to create a Singleton is by Singleton::createInstance(), and if you read the code, only the first time that we call Singleton::createInstance() a new instance is created.
All subsequent calls to this method will return the already created object. So in all your execution you will only have one instance created.
But of course... you should delete the line
Singleton sing;
because it is a wrong utilization of Singleton. If you create a class called CAR but without wheels... it is not a car. And you make a class called singleton, but... with two objects of the same type. It's not beauty!
I've got simple singleton class:
class Singleton
{
public:
static Singleton& getInstance()
{
static Singleton instance;
return instance;
}
// private constructor, etc...
}
The question is how should I access class instance from its member functions?
I've seen various code snippets and now I'm curious whether they have any significant differences.
1.
void Singleton::something(){
Singleton &self = getInstance();
self.doSomething();
}
2.
void Singleton::something(){
this->doSomething();
}
3.
void Singleton::something(){
doSomething();
}
is unnecessary complication - in a non-static member function like something we already have an instance, so there is no need to get it separately.
and 3. are the same, only 3. is shorter and more idiomatic - using this-> to access a member in C++ is not common.
I don't think there should be any other member function to get class instance except Singleton::getInstance();, because this is why it exist. Do it as below:
Sungleton &dst=Singleton::getInstance();
In fact, no way to get instance from non-static member function. When there is no class instance , how can you call its non-static member.
I was wondering if (in C++) you can instantiate a class (class foo) then have said class return the already instantiated object. (foo::instance())
In other words, can I have a class return it's-self via it's own methods? I want to be able to create a class (i.e. class foo) early in my program so it is already setup and ready to go. Then, farther down the line, I want to be able to call functions from that class without having to pass that object as an argument to my calling function. Can I do something like so:
MyClass::ReturnSelf()->foo();
or
MyClass::ReturnSelf().foo();
EDIT: I just realized this might be a little unclear. I want to be able to have another class call this "self-returning" method so it can use the already instantiated object's methods and members without creating a new object.
Congrats, you've discovered the singleton pattern. Quite a caveat, if you didn't already know it.
struct X
{
static X& instance()
{
static X x;
return x;
}
void foo();
};
and call the method as:
X::instance().foo();
Of course, you could also make the method static, if that's an option, and call it directly:
X::foo(); //this requires foo to be declared static
The effect of returning the instance from methods can also be used for method chaining:
struct Element
{
Element& setColor() { return *this; }
Element& setWidth() { return *this; }
};
Element e;
e.setColor().setWidth();
A static member function usually does the trick:
struct Foo
{
static Foo & special_instance()
{
static Foo impl; // Alarm bells: This is a global state!
return impl;
}
// ...
};
Usage (from anywhere in the code):
Foo & f = Foo::special_instance();
// ...
You have the additional option of making all the constructors of the class private so that this sort of object creation is the only option. This is generally awkward design, but there may be situations where it is useful. Just be mindful whether you're modeling your problem correctly or whether you might get away with something simpler.
I just realized this might be a little unclear. I want to be able to have another class call this "self-returning" method so it can use the already instantiated object's methods and members without creating a new object.
define a class-variable in class foo of type foo that you can return in static class method instance(). You may also try to give it type *foo and set it up with a pointer on first ctor, wich makes it possible to derive from your class.
class Foo
{
# class variable pointing to first instance
static foo* pFoo = null;
# constructor, sets pointer to first instance
Foo()
{
if (!pFoo) pFoo = this;
/* ... */
}
# static class method returning instance
static foo* instance() {return pFoo;}
}
How can I create a singleton class in C++/CX?
First, consider whether you really need a singleton.
There's no real difference in how one implements a singleton in C++/CX as opposed to ordinary C++. You need to do two things: (1) prevent construction of multiple instances, and (2) provide access to a single, global instance of the object.
Here's a trivial example:
namespace Component
{
public ref class Singleton sealed
{
public:
static property Singleton^ Instance
{
Singleton^ get()
{
static Singleton^ instance = ref new Singleton();
return instance;
}
}
private:
Singleton() { }
};
}
I've used a local static variable for the singleton instance, to avoid namespace-scope static initialization ordering issues. Visual C++ does not yet support C++11's thread-safe static initialization, so if you may be using the single instance from multiple threads, either you'll want to consider using a namespace-scope static variable and working through any potential initialization ordering issues, or you'll need to investigate synchronizing the initialization.
The way I do this is to have a static variable for a pointer to your singleton class initialized to NULL and a private constructor. Then use a static Create(...) method to build an instance. In the static Create method check the static variable and only build an instance if its NULL
class Foo
{
public:
Foo* Create();
private:
Foo(); //private ctor
static Foo* M_ClassDataP;
};
Foo* Foo::M_ClassDataP = NULL; //initialize class data ptr to null
Foo* Foo::Create()
{
if (NULL != M_ClassDataP)
{
M_ClassDataP = new Foo();
}
return M_ClassDataP;
}
I want to know why cant we create object if the constructor is in private section. I know that if i make a method static i can call that method using
<classname> :: <methodname(...)>;
But why can't we create object is what I don't understand.
I also know if my method is not static then also I can call function by the following:
class A
{
A();
public:
void fun1();
void fun2();
void fun3();
};
int main()
{
A *obj =(A*)malloc(sizeof(A));
//Here we can't use new A() because constructor is in private
//but we can use malloc with it, but it will not call the constructor
//and hence it is harmful because object may not be in usable state.
obj->fun1();
obj->fun2();
obj->fun3();
}
So, my question is: why can't we create an object when constructor is private?
Because it is not accessible to the program, that's what private means. If you declared a member function or variable private, you would not be able to access them either. Creating private constructors is actually a useful technique in C++, as it allows you to say that only specific classes can create instances of the type. For example:
class A {
A() {} // private ctor
friend class B;
};
class B {
public:
A * MakeA() {
return new A;
}
};
Only B can create A objects - this is useful when implementing the factory pattern.
A constructor is a special member function. It obeys the same rules as any other method when it comes to accessing it. The private access label prevents class users from invoking/accessing members declared under it.
The "new" operator needs to call the constructor, so if the constructor is private you can not execute the code "obj = new A" except inside member functions of the class A itself.
I would guess that what you have encountered is a technique that is very often used in Java (and yes I know you're writing C++, but the principle is the same) where the designer of the class wants to make sure that one and only one instance of this class will ever exist (which is called a "singleton"). To achieve this, he needs to prevent other code from creating further instances of the class using new, and making the constructor private is one way to do that. Here's a piece of Java code illustrating the technique.
public class MySingleton {
private MySingleton() {
// Private constructor, to prevent instantiation using "new"
// outside of this class.
}
public synchronized static MySingleton getInstance() {
static MySingleton instance = null;
if (instance == null) {
// I can use new here because I'm inside the class.
instance = new MySingleton();
}
return instance;
}
}
Even if you don't know Java, the syntax is similar enough to C++ that you should understand what this code is doing. The point is that the only way to get a reference to an instance of the MySingleton class elsewhere in the code is to call the static class member getInstance().
MySingleton obj = MySingleton.getInstance();
You can't instantiate your class because the constructor is private. private member variables and functions cannot be used outside of the class itself.
If you want to be able to instantiate your class, you have two options.
Option 1 is to make the constructor. This is the Right Thing to do in the vast majority of cases. Making a constructor private is a useful technique, but only when trying to accomplish specific goals.
Option 2 is to create a public static factory method. You would typically do this when Option 1 isn't an option.
class A
{
A();
public:
static A* Create() { return new A; }
void fun1();
void fun2();
void fun3();
};
int main()
{
A *obj = A::Create();
//Here we can't use new A() because constructor is in private
//but we can use malloc with it, but it will not call the constructor
//and hence it is harmful because object may not be in usable state.
obj->fun1();
obj->fun2();
obj->fun3();
}