In a class I have a static member that represents the singleton instance of that class:
class A {
public:
static const std::shared_ptr<A> INSTANCE;
private:
A();
};
In order to prevent more instances I made the constructor private. Now I have trouble to initialize the static var, because the initializer cannot access a private member. Here's the code I use in the .cpp file:
const std::shared_ptr<A> A::INSTANCE = std::make_shared<A>();
A factory method wouldn't help either, as it would have to be public as well. What else can I do to make this work? Note: I'd like to avoid the typical static get() method if possible.
You can't use make_shared, but you can just create the instance directly:
const std::shared_ptr<A> A::INSTANCE { new A };
The initialization of a static member is unrelated to the constructor, so the global statement is indeed the right way to go. Is it not working for you?
EDIT: I just realized you're trying to avoid using a singleton access method for some reason. Sounds suspiciously like the Borg pattern. :) Unrelated to you r specific question but I'd advise you to reconsider.
Related
I am accessing non static method from static Method. Below is the code. I read its bad design source. Why this bad design please help me to understand.
If so how can one achieve it.
#include<iostream>
class Base
{
public :
static Base* initialiser;
void BaseMethod()
{
std::cout<<"Non static method Invoked"<<std::endl;
}
static Base* GetInstance()
{
if (!initialiser)
initialiser = new Base();
return initialiser;
}
};
Base* Base::initialiser = nullptr;
class Service
{
public:
void ServiceMethod()
{
Base::GetInstance()->BaseMethod();
}
};
int main()
{
Service obj;
obj.ServiceMethod();
}
Why is accessing a non static method from static method is Bad design
It is not per se, as you are actually using a static member from a static methods
Yet this code snipped is too damn rigid, too damn over-engineered. Which means more likely to be buggy, to be a mess once a new requirement come into play.
defect : This code isn't thread safe. You should instantiate initializer not in GetInstance,rather using Base* Base::initialiser{new Base()};, which is guaranteed to be thread-safe from c++11.
defect : A class such like this should be derived with extreme caution. Or add final to prevent this possibility.
design : This code has still zero line of functionality. You are still plumbing. You want to reconsider if this is the best design for the problem being solved.
design : The purpose is to provide a singleton. We dev like to enforce unnecessary constraints such as uniqueness. When the time comes to support two instances in a system designed for a singleton, we have to refactor a whole lot of things.
Since the question was for a general case, here is a quote from Wikipedia:
Static methods are meant to be relevant to all the instances of a class rather than to any specific instance.
A static method can be invoked even if no instances of the class exist yet.
Thus, you should consider static methods to be in class namespace meant for operations on a class rather than on instances/objects of the class.
In your case of making singleton, your are not accessing non-static method from a static one, but you are initializing an instance of that (static) object initialiser within the static method.
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.
Take the below code. If I were to add some private member data into this class, say a std::vector, would I make it static or not?
#include <string>
class Logger{
public:
static Logger* Instance();
bool openLogFile(std::string logFile);
void writeToLogFile();
bool closeLogFile();
private:
Logger(){}; // Private so that it can not be called
Logger(Logger const&){}; // copy constructor is private
Logger& operator=(Logger const&){}; // assignment operator is private
static Logger* m_pInstance;
};
**Code example shamelessly taken from here
Idiomatically, no. Other than that, there's nothing that keeps you from doing it.
Keep in mind though that if it is static, it needs to be defined and the member gets initialized before entry to main, when the program starts.
If it isn't static, it will get initialized when m_pInstance gets created (which can be useful if you need some lazy initialization).
The big problem is order of initialization. In C++, the singleton idiom
is usually used to resolve order of initialization issues, so that's
likely to be a problem: if the members are static, you can't be sure
that they have been constructed before you try to use them.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is so bad about singletons?
Singleton pattern in C++
I want to create a singleton class. For that, I created a class with all its member and methods as static. Something like this.
class a
{
static int a;
static GetA();
}
Now all the classes who want to use my singleton class cannot create any object for my class and also will get same value. I just want to know whether this implementation will solve all the purpose and fulfill all criteria for creating a singleton class.
I prefer:
GlobalObjectMgr& GlobalObjectMgr::instance()
{
static GlobalObjectMgr objMgr;
return objMgr;
}
There is no class member variable required and it is created only when needed.
The conventional Singleton (anti-)pattern isn't a collection of static variables; rather, it is an object with non-static members, of which only one instance can exist.
In C++, this allows you to avoid the biggest problem with static variables: the "initialisation order fiasco". Because the initialisation order is unspecified for static variables in different translation units, there's a danger that the constructor of one might try to access another before it is initialised, giving undefined behaviour. However, it introduces other problems (a similar "destruction order fiasco", and thread safety issues in older compilers), so it's still something to avoid.
If you want a collection of static variables and functions, then put them in a namespace rather than a class:
namespace stuff {
int a;
void do_something();
}
If you think you want a singleton, then think again; you're generally better avoiding globally accessible objects altogether. If you still want one, then you would make a class with a private constructor, and a public accessor that returns a reference to the single instance, along the lines of:
class singleton {
public:
singleton & get() {
static singleton instance;
return instance;
}
int a;
void do_something();
private:
singleton() {}
~singleton() {}
singleton(singleton const &) = delete;
};
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();
}