C ++ static, using extern with global data

I am new to C ++ and OOP in general and have been trying to find out effective or β€œright” ways to do something, but I still have problems.

I am creating a DataStore class that contains data for other classes / objects. There will be only one instance / object of this class; however, it is not really necessary to be an object / instance, as this is global data. In this case, I feel that this is just a way to provide scope. So, I want to directly change the members of the class instead of going around the object. I read about static and _extern, but I can't decide if it will be viable or if something else would be better.

Right now I am passing one created object to change its data, but I would prefer the class to be available as "itself" rather than "one instance of itself", while preserving the idea that it is an object.

+4
source share
4 answers

EDIT: The OP comment explains that the data store will be read by code running on multiple threads, and updated by code on the same thread. My previous answer no longer applies. Here is the best answer.

Do not use a global variable to store the storage instance. This will open the door to many subtle mistakes that can haunt you for a long time. You must provide read-only read access in the repository. Your message stream must have read and write access.

Make sure your read methods in the data store are marked as const . Then create one instance of the data warehouse and place the pointer to it in the global variable const . Your GetInstance stream should have a different mechanism for obtaining a non-constant pointer (add the public static GetInstance method, as suggested by @Mats).

My previous answer: If you are sure that there will always be only one instance of the data store, do not skip it.

Global variables are not approved, and some languages ​​(Java and C #) outlaw them. So in C # and Java, instead, you are using static class members that are pretty much the same (with exactly the same problems).

If you can put one instance in the global variable a const , you should be fine.

If you are doing multithreading, you need to make sure your store is thread safe, otherwise there will really be bad things.

+1
source

As a rule, such a problem (where you need one, but only one - and you are sure that you will never need more) is solved using the "singleton" template.

 class Singleton { public: static Singleton* getInstance() { if (!instance) instance = new Singleton(); return instance; } int getStuff() { return stuff; } private: Singleton() { stuff = 42; } static Singleton *instance; int stuff; }; 

then in some suitable .cpp file>

 static Singleton *instance; 

Or use the global variable directly:

 class Something { public: Something() { stuff = 42; } int getStuff() { return stuff; } private: int stuff; } extern Something global_something; // Make sure everyone can find it. 

In ONE .cpp file:

 Something global_something; 

Since BOTH is essentially a global variable solution, I expect someone who doesn't like global variables to downgrade it, but if you don't want to distribute your class object everywhere, a global variable is not a terrible idea. You just need to know that global variables are not necessarily a great idea as a solution in general. It will be difficult to keep track of what is happening, and it certainly becomes messy if you suddenly need more than one (because you decided to change the code to support two different repositories or something else), but this also applies to the single.

+3
source

you can use the controversial Singleton template, or you can use one of the PARAMETERISE FROM ABOVE methods described in Mark Radford (overload log # 57 - Oct 2003) SINGLETON - article against the template! .

PARAMETERISE FROM ABOVE (in his opinion) enhances encapsulation and facilitates initialization problems.


Classic lazy priced and properly destroyed singleton:

 class S { public: static S& getInstance() { static S instance; // Guaranteed to be destroyed. // Instantiated on first use. return instance; } private: S() {}; // Constructor? (the {} brackets) are needed here. // Dont forget to declare these two. You want to make sure they // are unaccessable otherwise you may accidently get copies of // your singleton appearing. S(S const&); // Don't Implement void operator=(S const&); // Don't implement }; 

But note: this is not thread safe.

fooobar.com/questions/6059 / ...

+1
source

I do this for an object that has 1 instance most of the time during program execution.

 class Object { private: Object(); friend Object & GetObject(); public: ... }; inline Object & GetObject() { static Object O; return O; } 

1) it is less verbose than singleton.
2) this prevents the trap of a global object, for example, an undefined initialization order.

+1
source

Source: https://habr.com/ru/post/1489964/


All Articles