views:

250

answers:

9

In a C++ multi-threaded application with many classes, i am trying to find out what are the methods to define a global variable

  1. C style, define it as global in any one source file, define it as extern in a header which is included in the classes that access this variable.

  2. Write a Singleton class, which contains these global variables and exposes set/get methods to write to the variable.

By second method one can control multi-threaded access via locks in a centralized manner rather than the first approach.

Are there more and better ways?

+3  A: 

I would definitely go with the Singleton class. It's the best way to handle "global" variables in a multithreaded OOP environment.

mozicodo
The singleton pattern is complicated by having to cope with the possiblility that any thread might trigger the initialization of the object. Most singleton implementations allow multiple threads to access the singleton simultaneously via a "get reference" method" so don't address any synchronization issues arising with the use of the object itself. I don't see any strong reason why a singleton class is the best solution.
Charles Bailey
+1  A: 

If you must use a global variable (and why are you using one?) I recommend the second way you described. The first way is the way you can run into all kinds of namespace problems.

Starkey
+4  A: 

First of all try to avoid global variables as much as you can. If you just need to do it (by example this is the case with cin, cout and cerr) your second method is definitely the best (and more natural) way of doing it.

Dacav
A: 

It depends on the problem at hand.

C-style globals have the advantage of simplicity, no need for Singleton::instance() call. However, Singleton::instance() allows you to initialize your global state on the first call.

To get the best of both worlds use C-style globals initialized using Schwarz Counter method. http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter

Maxim Yegorushkin
Bad idea that is badly implemented.
Martin York
+3  A: 

If the scope of your "global variable" can be narrowed down (which is typically the case - how many variables are truly global?) then you can make it a private static class member in the appropriate owning class. If your other classes need to see it (or less likely, update it), provide get/put accessors.

Steve Townsend
A: 

You can define a value object that wraps a single implementation with the handle/body idiom.

Also review "Modern C++ Design" by Alexandrescu for discussion about the difficulties of implementing singleton in MT environments and how to go about addressing them.

Noah Roberts
+1  A: 

Hi,

This probleam can be solved with an alternatieve method very easily.

C++ resolves this problem very easily by its new operator :: called scope resolution operator. The syntax is as follows

:: variable-name;

This operator allows access the global version of a vriable.

ksrao
A: 

Not to kick a dead horse but, as mentioned, avoiding globals is the best solution. Some reasons are listed here. If a global variable is a must you might want to consider providing a function to access it from to avoid the so called 'global initialization fiasco'.

skimobear
+1  A: 

One tends to prefer the second method, because it seems to give you a better control but it may not turn out very useful in some scenarios.

First, In my understanding of philosophy of OOP, I do not consider objects as collections of bunch of data, but entities in terms of which, you can represent real world problems. So I do not consider it a good idea to to have a class to store random data. Especially when the data members are largely unrelated.

Second, If you are thinking of having a central control eg. having a single mutex to access all the data members, this is not going to work out very well for unrelated data members. You are going to block a lot of threads unnecessarily while the data they want is not exactly the one which is being currently protected by the lock.

So it may seem strange, but I would prefer the first method.

Swapnil