Global Variable

Dec 20, 2009 at 4:14pm
This is my pseudo_code:

1
2
3
4
5
6
7
8
9
10
Cgicc cgi;

class My_Class
{
    public:
    My_Class()
    {
         cgi.getFile();
    }
};


When I compile this it doesn't work. The message is:
multiple definition of `cgi'


So my question is how do I make a global variable which I can use also in my class My_Class. With static it doesn't work and also
Dec 20, 2009 at 4:35pm
Is all that in a header file?
Dec 20, 2009 at 5:28pm
Global variable? Are you sure you want to do that?

The actual problem you have here is that you appear to have defined an object, cgi, in your header file. Each compilation unit comes along and sees the definition and creates a cgi. At link time, the compiler sees many object files, each defining a cgi.

The use of globals is not good and you really should think about why you have one.

But to fix the mechanics of what you're doing wrong is to use:
1
2
3
4
5
6
7
8
9
10
extern Cgicc cgi;

class My_Class
{
    public:
    My_Class()
    {
         cgi.getFile();
    }
};

This says, I'm using a global cgi, and it's of type Cgicc. You'll see the definition somewhere else.
Dec 20, 2009 at 5:32pm
Globals are ugly for many reasons. My advise would be to rethink your approach here.

If you really do want to use a global....

It's kind of like with functions. If you want a function available to many .cpp files, you put the prototype in a header, but you put the actual function body in a cpp file. With variables it's kind of the same way. You put the extern declaration in a header (so many files can see it), but put the actual variable in only 1 cpp file (so it's only actually created once).

ie:

1
2
3
// globals.h

extern Cgicc cgi;

1
2
3
// globals.cpp

Cgicc cgi;

1
2
// any other cpp file you want to have access to the globals
#include "globals.h" 


If you have a lot of globals and don't want to declare them all twice like that, you can use a macro trick:

1
2
3
4
5
6
// globals.h
#ifndef GLOBAL
#define GLOBAL extern
#endif

GLOBAL Cgicc cgi;

1
2
3
// globals.cpp
#define GLOBAL
#include "globals.h" 

1
2
// all other cpp files you want the globals for
#include "globals.h" 


This trick has 'globals.cpp' #define GLOBAL as nothing, so when you include globals.h, the variables aren't declared as extern. All other cpp files don't define GLOBAL, so when they include globals.h the variables are declared as extern.


But again.. I have to stress that globals are a very poor design decision most of the time. If this 'cgi' variable is only going to be used in My_Class, then you're better off making it a static member:

1
2
3
4
5
6
// myclass.h
class My_Class
{
//...
  static Cgicc cgi;
};

1
2
3
// myclass.cpp

Cgicc My_Class::cgi;


EDIT: doh I'm too slow. Oh well ^^
Last edited on Dec 20, 2009 at 5:32pm
Dec 20, 2009 at 6:00pm
REALLY FAAAAAAAAAAAAST :)
Cool that was a real good help. Good explanations.
Yeah I know that it is poor design, but I have to because CGI is not my variable. It is a global variable of the library cgi. And not only my My_Class use this variable. All my webclasses use it.
THANKS ... now it works!
Last edited on Dec 20, 2009 at 6:01pm
Dec 20, 2009 at 6:01pm
closed account (1yR4jE8b)
Globals are EVIL, the sooner you learn that the better.

Instead of having a global variable, why don't you pass a local variable into the class using the constructor. That is what parameter passing is for after all...

something similar to this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "Cgicc"

class My_Class
{
    public:
    My_Class(Cgicc cgi)
    {
         cgi.getFile();
    }
};

int main()
{
     Cgicc cgi;
     //initialize cgi somehow

     My_Class object = My_Class(cgi);
}
Dec 20, 2009 at 7:23pm
This would also a possibility I think. But for the moment I don't care. :D
I know that globals are evil, but with c++ you have full access to the evil :D
Last edited on Dec 20, 2009 at 7:24pm
Topic archived. No new replies allowed.