PDA

View Full Version : Global variables



Mariane
1st February 2006, 18:10
I know I'm not supposed to use them, but they make life easier...

Well, no so easy... :

I started by writting in a file called globalVariables.h:


#ifndef GLOBALVARIABLES_H
#define GLOBALVARIABLES_H 0
int ** Log;
#endif


Then in maze.cpp and in mazeform.ui.h I did #include "globalVariables.h"
(I tried to add globalVariables.h in maze.pro, then I removed it, it doesn't
change anything). I get

g++ -o maze .obj/maze.o .obj/mazebox.o .obj/main.o .obj/lcdrange.o .obj/mazeform.o .obj/qmake_image_collection.o .obj/moc_lcdrange.o .obj/moc_maze.o .obj/moc_mazeform.o -L/usr/share/qt3/lib -L/usr/X11R6/lib -lqt-mt -lXext -lX11 -lm
.obj/mazeform.o(.bss+0x0): multiple definition of `Log'
.obj/maze.o(.bss+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [maze] Error 1

BUT when I remove the #include directive from mazeform.ui.h, I get

mazeform.ui.h: In member function `virtual void MazeForm::fileSave()':
mazeform.ui.h:72: error: `GLOBALVARIABLES_H' undeclared (first use this
function)
mazeform.ui.h:72: error: (Each undeclared identifier is reported only once for
each function it appears in.)
mazeform.ui.h:73: error: `Log' undeclared (first use this function)
make: *** [.obj/mazeform.o] Error 1

(I was also testing to see if it knew GLOBALVARIABLES_H)

AND when I remove the #include from maze.cpp I get

maze.cpp: In member function `void MazeField::intialiseLog()':
maze.cpp:89: error: `Log' undeclared (first use this function)
maze.cpp:89: error: (Each undeclared identifier is reported only once for each
function it appears in.)
make: *** [.obj/maze.o] Error 1


Please tell me WHERE I'm supposed to #include "globalVariables.h" so that
all files have acces to it and it doesn't get included too often (ignoring the
preprocessing directives?)???.

Thank you

Mariane

jacek
1st February 2006, 18:25
I started by writting in a file called globalVariables.h:


#ifndef GLOBALVARIABLES_H
#define GLOBALVARIABLES_H 0
int ** Log;
#endif

The problem is that you will have a different Log variable in every .cpp file that includes globalVariables.h, because that .h file contains definition of Log variable instead of forward declaration.

What you need is:

// globalVariables.h
#ifndef GLOBALVARIABLES_H
#define GLOBALVARIABLES_H
extern int ** Log;
#endif

// globalVariables.cpp
int ** Log = 0;

But maybe you should consider using the singleton pattern?

Mariane
1st February 2006, 18:36
Thank you, I'll try this.

What is a singleton pattern, please?

Mariane

Mariane
1st February 2006, 18:39
It works! Thank you very very much :) :) :)

Mariane

jacek
1st February 2006, 18:51
What is a singleton pattern, please?
Singleton is just a way of hiding the fact that you use a global variable. It also ensures that you have at most one instance of that particular class.

There are many ways to implement it, but it's usually something like this:
class Singleton
{
public:
static Singleton * instance()
{
if( _instance == 0 ) _instance = new Singleton();
return _instance;
}

// ...

private:
Singleton() { /* ... */ }

static Singleton *_instance;
};You can use Singleton::instance() to access it (just like QApplication::instance() in Qt4).

sunil.thaha
2nd February 2006, 04:54
Instead of Using Singleton Pattern Why not define an class with Static get/set functions ?



class GlobalData{
public:
static int userId(){
return sm_iUserId;
}

static void setUserId( int iUserId ){
sm_iUserId = iUserId;
}

private:
static int sm_iUserId

};

jacek
2nd February 2006, 14:36
Why not define an class with Static get/set functions ?
Isn't that just a form of a singleton?

high_flyer
2nd February 2006, 15:25
Isn't that just a form of a singleton?
Yes, static simply put is a global in a scope/namespace/class.

yop
2nd February 2006, 21:56
Singleton is just a way of hiding the fact that you use a global variable...
it's usually something like this...I also like this approach

class Singleton
{
public:
friend Singleton &instance()
// ...
void doSomething();
private:
Singleton() { /* ... */ }
};

Singleton &SingletonInstance()
{
static Singleton aSingleton;
return aSingleton;
}


And the call to the instance is just SingletonInstace().doSomething()
Both ways are really effective ;)

sunil.thaha
3rd February 2006, 05:07
Isn't that just a form of a singleton?
Does your approach have any advantage ?

jacek
3rd February 2006, 10:46
Does your approach have any advantage ?
Yes, you can have a constructor (and with a little effort a destructor too).

sunil.thaha
3rd February 2006, 11:36
Yes, you can have a constructor (and with a little effort a destructor too).

Thought, it was a joke.
But on second thought then You r Right

Chicken Blood Machine
28th February 2006, 04:28
Thought, it was a joke.
But on second thought then You r Right



You can also use signals and slots with Jacek's implementation.

merlvingian
9th October 2006, 04:56
class Singleton
{
public:
static Singleton * instance()
{
if( _instance == 0 ) _instance = new Singleton();
return _instance;
}

// ...

private:
Singleton() { /* ... */ }

static Singleton *_instance;
};

It appears that this would need a delete() call at some point to prevent memory leaks. If it was subclassed from QObject wouldn't it be included as part of its garbage collection by calling:

Singleton->setParent(qApp);

I understand it's an abstract example but I contemplating using singletons in some code and need to know how to handle their cleanup properly.

Chicken Blood Machine
10th October 2006, 18:23
You can use qAddPostRoutine in <QApplication> to celan up non-QObject descendents.

But, to be honest, a singleton is usually supposed to exist for the duration of the program execution. In these cases, it is not really a memory leak for the object to still exist at shutdown (unless it is important for some reason that the destructor is called).