PDA

View Full Version : how to declare custom namespace for GUI applications?



szisziszilvi
15th August 2011, 14:32
Hi,

I would like to add a custom namespace to my Qt GUI application. How should I do that?

Here are the details and what I have tried:

If I create a new Qt console application and I change the main.cpp to this:


// ... includes
namespace
{
int x = 1;
}
int main(int argc, char *argv[])
{
// whatever I wish
}

it works fine.

But if I create a new Qt GUI project I don't know then where to add the namespace code. If I just try to add it to the mainwindow.h like below then it fails:


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

//only this short code is added:
namespace myn
{
int x = 1;
}

class MainWindow : public QMainWindow
{
// ... (nothing is changed here compared to the default new project opening)
};

#endif // MAINWINDOW_H
The error message is that multiple definition for myn::x is given.

I also tried to add a c++ header as if i wanted to create a new class and include it but it did not work. I tried then to add a class with a proper header and and cpp, and defined the namespace befeore the declaration of the class and the strange result is that it can be compiled and it runs as long as I don't use anything from the namespace. But if I put say a spinbox on the gui and I write into the constructor:
ui->spinBox->setValue(myn::x);
it complains again for multiple definition.

Why is this whole? How can I use than custome namespaces for my Qt Application?

Szilvi

Santosh Reddy
15th August 2011, 15:06
This should go into a .cpp file, and in the header file just the extern declaration

namespace myn
{
int x = 1;
}

szisziszilvi
15th August 2011, 15:37
this may be a silly question but what is an extern declaration? I tried to google it but I just found external variable but that is something else.

wysota
15th August 2011, 16:10
No, that's exactly it.

szisziszilvi
15th August 2011, 18:26
aha, so after some tries... this is it:
I created a new "class" that contains actually no class but looks like this:
nsclass.h:


#ifndef NSCLASS_H
#define NSCLASS_H

namespace myn
{
extern int x;
}
#endif // NSCLASS_H

nsclass.cpp:


#include "nsclass.h"

namespace myn
{
int x = 11;
}


and of course I included the header in the mainwindow.h and now it works.


But I still don't really get the reason why and why not when I leave this whole "extern-game". Could you please explain me this a bit?

wysota
15th August 2011, 21:22
Here is a practical explanation.

Suppose you had the following incl.h file:

#ifndef INCL_H
#define INCL_H

int x = 10;
#endif

And then you had a file a.cpp such as this:

#include "incl.h"

int func1() { return x; }
and another one, b.cpp, such as this:

#include "incl.h"

int func2() { return (x+1); }

Now suppose you have some other piece of code that contains:

int x1 = func1();
int x2 = func2();

When the compiler compiles a.cpp into a.o, it includes the incl.h file which declares a "x" variable and func1() can see the variable and operate on it.
Now when the compiler compiles b.cpp into b.o, it includes the incl.h file which also declares a "x" variable and func2() can see it and operate on it.
Now the linker tries to consolidate modules of your program into a single executable. It looks at a.o and sees it has a declaration of variable "x". But b.o also has a declaration of variable "x". To the compiler those are two different variables and it can't cope with such a situation and returns an error. Why? What if it didn't, that's the same variable isn't it? Ok, but what if a.cpp declared x as an integer with value "11" and b.cpp declared it with value "-1"? What would the values of x1 and x2 be after the last snippet?

What "extern" does is that it says "somewhere out there there is a variable called x". There is no declaration here, just an info for the preprocessor and compiler that "x" is a valid integer variable. It means you have to declare this variable somewhere and that's what you do in your "nsclass.cpp". Then the compiler sees only one "x" variable and two "placeholders" for an x variable. There is no conflict and linking can succeed.