I heard that using global variables is very bad. Is it possible to completely get rid of in this case? For example, there is a plugin for downloading an image and translating it into a regular format.

CPlugIn* plugin; extern "C"{ __declspec(dllexport) bool PlugInStart( void ){ plugin = new CPlugIn(/*params*/) if( !plugin ){ /*error*/ return false; } return true; } __declspec(dllexport) unsigned char* PlugInGetImage( const std::string& file_name ){ return plugin->LoadFile( const std::string& file_name ); } __declspec(dllexport) void PlugInStop( void ){ delete plugin; } } 
  • 2
    It is not at all clear from your sample code whether the client code should refer directly to the pointer, or it should deal with functions. If it has to deal only with functions, then why did you declare the pointer global? - Vlad from Moscow
  • 3
    Generally speaking, if global variables were only evil, they would be removed from languages, but they are obviously necessary, like goto, in some places. Judging by the type and name of your variable, its global assignment can be justified - it uses a low-level DLL module entirely. Bad global variables are variables in the spirit of "int i", "bool tmp_1, tmp_2", etc. So if your concern is caused only by the semantic aspect - you can not worry. - AseN
  • new way, throws an exception when it is impossible to allocate memory. To check for nullptr you need to add nothrow - αλεχολυτ

3 answers 3

In this case, you have turned out to be a loner , judging by the given fragments. Although the widespread loners and the same problems as the global variables. In your case, this is more a realization detail. Therefore, nothing needs to be done, in this form it is tolerable.

However, I would like to note that your PlugInStart and PlugInStop look rather superfluous. They need to be called to DllMain because the client does not need to know that the extension needs some additional kicks to work. In other words, with this design you do your hands decapsulate implementation details.

Heard that using global variables is very bad.

Hearing is not enough, you have to understand.

You should not be led to "common" opinions, even if Alexandrescu himself whispers on the phone. Solves common sense .

How many copies are broken in disputes over global variables regarding the use of the goto operator. And nothing has changed. It is not the “popularity” of designs that decides the quality of the code, but their relevance to current use.

On examples

We need a Config object. Having made it a singleton, or simply a global access structure, we do not lose anything. Overhead zero! He is alone. By making setters and getters thread-safe, we'll generally be cross-threading. But we can drive it by reference to objects ... just to let the posons say: “Bah, you don’t have global objects, you will code as the majority accepted!”

Yes, yes, of course: tens of thousands of flies can not be wrong - this is honey!

Do I need a goto ? Yes or no? "The right posony" will authoritatively say - not needed. There are primitive functional constructions with which to build everything. Only the “left” progs use this.

Let me remind you - tasks are different. For example, building an automaton on a sparse state matrix (well, for example 500x500) is much simpler on elementary switch (essentially goto ), than to build if - while nested in each other if / while / do .

Well, now subject

download any image

The essence of the "image" for the application is not a global concept. To be honest, except for the “config” (possibly, states), I no longer see applicants for the global scope.

    Formally, any global variable can be eliminated by making it static and returning via a function. Type

     CPlugIn* globalPlugIn() { static CPlugIn* plugin = 0; if (plugin == 0) plugin = new CPlugIn(/*params*/); return plugin; } 
    • one
      This does not change the essence, the variable remains global. - Cerbo
    • This changes the essence, because even though the variable is now visible from the global context, clients do not know about its existence - it turned out an artificial intra - modular encapsulation - AseN
    • @ 0xFFh: So it seems like there is no variable in the current code, it is in another DLL. Well, there you can register her namespace { ... } or static . - VladD
    • @Cerbo And you did not pay attention to the first word in my answer? - Harry
    • @Harry, why if? this is enough (and with C ++ 11 it’s also thread-safe): static CPlugIn *plugin = new CPlugIn(/*params*/) or even just static CPlugin plugin{/*params*/}; return &plugin static CPlugin plugin{/*params*/}; return &plugin . But in the second case, you need to understand when the object's destructor will be called and in case of loading / unloading the DLL you should closely monitor this. - Monah Tuk