Re: Global variable
On Mon, 22 Oct 2007 04:41:17 -0000, keralafood@gmail.com wrote:
Thanks..i tested both way..can anybody say CWinApp or static member
which is better approach?or both are same?
Because CWinApp is a global, they are more or less "the same", because
non-static members of an object have the same "storage duration" as the
object that contains them. Therefore, a non-static member of the one and
only CWinApp object is very much like a global that is scoped to the
CWinApp object. If you want to understand this better, read on, but I have
a feeling it could get a little long.
First, some background:
There are three types of data that have "static storage duration":
1. Global, or more generally, namespace-scope data,
2. Class static, which is essentially (1) declared inside a class using the
"static" keyword,
3. Local static (data declared "static" inside a function).
Here, we're talking about (1) and (2), and in VC++ and most other
compilers, they share the property that all such objects are initialized
before main() is entered. There are two considerations:
a. Visibility
b. Order of initialization
Concerning visibility, data and functions defined in the global namespace
(i.e. "true" globals) are visible throughout the program. You can control
this by defining things inside a namespace or a class. The "static" keyword
can be used to confer "file scope" to an object or function, but it is
deprecated WRT (1) in favor of anonymous namespaces; in particular, you
can't declare a class "static", and you must use an anonymous namespace
when defining a class that should have file scope.
Concerning order of initialization, objects of types (1) and (2) defined in
the same file are initialized in the order they are declared, while the
order is indeterminate for objects defined in different files. So consider
the following contents of a file a.cpp:
// a.cpp
X x;
namespace {
Y y;
}
X Z::x; // x is a static member of a class Z
Before main() is entered, x, y, and Z::x will be initialized, and in that
order. Now suppose there is another file, b.cpp, which contains:
// b.cpp
X bx;
It is impossible to say when bx is initialized relative to the objects in
a.cpp.
OK, enough background. :)
Tom's suggestion to stuff all the globals in a single file is a good one,
because it helps you control their order of initialization. I think it's
also good for organizational purposes.
The suggestion to define a class whose members are all public static is OK,
except that you can do the same thing with namespaces and eliminate any
question about creating instances of the class.
Finally, adding non-static members to CWinApp allows the CWinApp
constructor to use them, and it also ensures that those objects will have
been constructed by the time anyone who can validly use the CWinApp object
gets around to using it. Note that the one and only CWinApp object is a
global, so the order of initialization issue is important:
// a.cpp
CWinApp theApp;
X x;
// b.cpp
Y y;
Above, x can use theApp, but y cannot *validly* use it since it's defined
in a different file. If you wanted to put your globals in their own
namespace but allow theApp and x to use them during their construction,
you'd have to do it like this:
// a.cpp
namespace Whatever {
T t1;
T t2;
}
CWinApp theApp;
X x;
Getting back to your original question, it was:
How i can avoid global variable in my program?
I use 10-15 global variable because i have to use it different
callback functions(all are system callback, like hook,directX
etc...)is there any way to avoid this?
i must use these variables(some variable using in different file as
external variable)
If these callbacks, hooks, etc are major parts of your program, then
representing them inside CWinApp or in other conspicuous ways makes sense.
If they are just highly localized artifacts of Windows programming, e.g.
you find you need to use EnumSomething at some point, and the function
doesn't allow you to pass in an object of your own as a void* for your
callback function, I tend to handle this as follows:
// In the file that uses the callback, right before the function that uses
// the callback...
namespace {
int callback_data;
void callback_function()
{
// Use callback_data
}
}
I would not clutter other parts of the program with this sort of minutiae.
--
Doug Harrison
Visual C++ MVP