Using namespaces instead of single

I recently posted a question on SO regarding the use of a class that would ideally differ from individual functions. I was encouraged to learn about a singleton template to create only one instance of a class, and it manages a set of operations that revolve around the data that it encapsulates. You can see the question here - using a static container for the base and derived classes .


Now consider this code -

#include <iostream> #include <string> #include <unordered_map> class A{ std::string id; public: A(std::string _i): id(_i){} virtual void doSomething(){std::cout << "DoSomethingBase\n";} }; class B : public A{ std::string name; public: B(std::string _n):name(_n), A(_n){} void doSomething(){std::cout << "DoSomethingDerived\n";} }; namespace ListA{ namespace{ std::unordered_map<std::string, A*> list; } void init(){ list.clear(); } void place(std::string _n, A* a){ list[_n] = a; } } int main() { ListA::init(); ListA::place("b1", new B("b1")); ListA::place("a1", new A("a1")); return 0; } 

Ignoring the fact that I still use raw pointers that unload memory if the program does not exit as it is, is this a good alternative to using global static variables or a single?


As for the previous question, I reorganized class A (base class) and class B (derived classes) independent of the namespace that manages the list of these objects. So is this a good idea or an absolutely bad practice? Are there any drawbacks to this?

A good singleton implementation I was proposed as follows:

 class EmployeeManager { public: static EmployeeManager& getInstance() { static EmployeeManager instance; // Guaranteed to be destroyed. // Instantiated on first use. return instance; } private: EmployeeManager() {}; std::unordered_map<std::string, Employee&> list; public: EmployeeManager(EmployeeManager const&) = delete; void operator=(const&) = delete; void place(const std::string &id, Employee &emp){ list[id] = emp; } }; class Employee { public: virtual void doSomething() = 0; }; class Writer : public Employee { private: std::string name_; public: Writer(std::string name) : name_(name) {}; void doSomething() { }; }; 

Honestly, I have never tried a singleton template, and I try to use it directly, since I have no previous experience, and I would prefer to use it in my pet projects first.

+4
source share
3 answers

- is this a good alternative to using global static variables or singleton?

no, because you may run into another problem: the static fiasco of ordering . There are ways to fix this, but with functions with static variables that look single.

... but why do you need global variables (even in namespaces) or singleton? In the first example, it would be nice if instead of namespace ListA you had a struct ListA - plus delete that namespace{ . Then you have:

 int main() { ListA list; list.init(); list.place("b1", new B("b1")); list.place("a1", new A("a1")); } 

and everything looks fine.

Then your aproach singleton, once again - not necessary for this - create a variable of type EmployeeManager in your main function if you need to use it in some other class, and then pass it by reference or pointer.

+2
source

I'm not sure that you already know this, but you need to remember that Singleton is indeed a global variable with lazy initialization .

Lazy initialization is a tool to fix the problem of initializing an object always when you really want to use it - whether for some function of a real program or to initialize another dependent object. This is done to delay initialization until the first time the object is used.

A static object is simply initialized at the moment when it needs to create the first one , however, when it really is, it is undefined, at least in C ++.

You can replace lazy initialization with static initialization, but you must somehow make sure that the initialization happens in a specific order.

Defining variables within a namespace is nothing more than declaring variables globally. Namespaces are open, the rules inside the namespace are the same as outside the namespace, except for the resolution of the character.

What you can do to force initialization is to create one global variable with all the dependent global objects inside, in the form of a struct that will contain all of them as fields ( not static fields!). Please note that the exact initialization order will be provided only between objects that are fields of this structure, and not between them and any other global objects.

+1
source

You can answer your question without any line of code, as in the past many people have answered this. Singletones are bad because your code will depend on one class and its implementation. However, you want to have independent blocks that are not aware of the implementation of the interfaces with which they communicate. The distribution of values โ€‹โ€‹/ references should (in fact, this should be done for large supported systems) by means of a link passing from the containing object to its child, the observer / event system or the event / message bus. Many structures use two approaches to these approaches ... I highly recommend following best practices.

0
source

All Articles