Header questions

Hi,
am still quite new to c++ and was wondering if I were to declare

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef InputHandler_H
#define InputHandler_H

IDirectInputDevice8* DIKeyboard; // These two
IDirectInputDevice8* DIMouse; //These two
 
DIMOUSESTATE MouseLastState;
LPDIRECTINPUT8 DirectInput;


bool InitDirectInput(HINSTANCE hInstance);
bool DetectInput(double time, HWND hWnd);

float mouseRotationY;
float mouseRotationX;
float mouseRotationZ;
float scaleX;
float scaleY;
float zoomSensetive;

#endif 

in a Header why would there be a problem if I include it into two diffrent cpp files?
One of the error says that The variable have already been defined.
But in the two file I included the header
one of them only use it to Release the object.
while the other do everything else.
So would anyone mind explaining to me why?
Last edited on
You've stumbled into a nice can of worms that C++ gives you. Disch here explains this pretty well:
http://www.cplusplus.com/forum/articles/10627/

Thanks for the link, It gave me very good knowledge on other things. But am still not sure where my problem really is. ;(
Maybe am just to dumb to understand the problem.
Unless the problems leads that I do not have the Pointers class declared/included? but it works when I only have one cpp file that include the header, or is it cause that I have two of the same thing declared in the program? but how come float x; works than? would you mind giving me a few more pointers?
Global variables are fraught with peril. Even moreso when those variables are in header files.

It's easier to explain in purposes of functions.

Say for example your program has two functions with identical names and signatures, in two separate cpp files.

EXHIBIT A:
1
2
3
4
5
6
// file1.cpp

void func()
{
  cout << "file1.cpp";
}

1
2
3
4
5
6
7
8
9
10
11
// file2.cpp

void func()
{
  cout << "file2.cpp";
}

int main()
{
  func();  // which 'func' does this call?
}


The problem here is that the linker sees two separate 'func' functions, so when you call func from main, it has no idea which function it's supposed to actually call. The file1 version or the file2 version?

The exact same problem occurs with variables.

EXHIBIT B:
1
2
3
//file1.cpp

int glb = 0;

1
2
3
4
5
6
7
8
//file2.cpp

int glb = 0;

int main()
{
  glb = 5;  // which 'glb' are you setting?  file1's or file2's?
}


This will give you the same linker error as exhibit A because you now have two externally visible variables named 'glb' and the linker gets confused as to which one of those two you actually want to use and where.



Now to expand this to what you're doing... you're putting a global variable in a header and including it in multiple cpp files. But this also does not work (as you're seeing).

EXHIBIT C:
1
2
3
//header.h

int glb = 0;

1
2
//file1.cpp
#include "header.h" 

1
2
3
4
5
6
7
//file2.cpp
#include "header.h"

int main()
{
  glb = 5; //  SAME PROBLEM.  See below
}


You might look at this and only see one 'glb' variable, but that's not what the linker sees. It still sees two. Giving you the same error as before.

What you have to remember is that #include is just a glorified copy/paste operation. When you include that header, the compiler will effectively drop the header file right into the cpp file. Giving you the exact same scenario as Exhibit B: both cpp files are creating their own variable. And therefore the exact same problem: the linker gets confused on which variable to use.


So how do you solve this?

The best way is to simply not use globals. Ever. (well okay there are some situations where they're handy, but it's not nearly as often as you'd think). Globals generally are messy and make your program hard to manage. Get in the habit of objectifying things, and/or passing them between functions as parameters, and other more typical techniques.


If you insist on using globals (booo)... read on:



[Partially] Solving by creating only one global variable.
EXHIBIT D:
1
2
// file1.cpp
int glb = 0;  // the one and only global variable 

1
2
3
4
5
6
// file2.cpp

int main()
{
  glb = 5; // not quite ok... but closer!
}


It's true that this code will work for the linker when it tries to combine all your compiled source files together. There is only one glb variable defined so it's clear which variable your program wants to use. However this won't even get to the linker because the compiler (which only ever sees one cpp file at a time) sees that 'glb' and doesn't know what the hell it is because it wasn't declared in this cpp file.

So now you'd get a compiler error about glb being undefined.


So how can we tell the compiler that a variable exists without actually creating it? The answer is the extern keyword.

EXHIBIT E:
1
2
//file1.cpp
int glb = 0;  // the one and only global variable 

1
2
3
4
5
6
7
//file2.cpp
extern int glb;  // tell the compiler is exists somewhere else, just not in this file

int main()
{
  glb = 5;  //NO PROBLEMO
}



Or... more traditionally, you would put the extern declaration in the header, and the actual variable definition in one and only one cpp file.
EXHIBIT F:
1
2
//header.h
extern int glb;

1
2
3
4
//file1.cpp
#include "header.h"  // strictly, this isn't necessary here... but it doesn't hurt.

int glb = 0;  // the one and only variable 

1
2
3
4
5
6
7
//file2.cpp
#include "header.h"

int main()
{
  glb = 5;  // NO PROBLEMO - header.h has the extern declaration so we're all good.
}





If this is confusing... it might help to equate to how functions work. Remember that you cannot have two different function bodies... just like you can't have two different variables. Functions have the way to prototype them so you can use them without actually having to give them a body... and variables can be declared as extern which is basically the same thing.

EXHIBIT G:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void func();  // a function prototype.  Tells the compiler the function exists
    // without actually giving it a body.

extern int glb;  // a variable prototype.  Tells the compiler a variable exists without
   // actually giving it a body.  Exact same idea.

/***********/

void func()
{
  // a function body.  Can only have one of these for this function in your program
}

int glb;  // a global variable.  Can only have one of these for this var in your program. 
Drop whatever job you have now and become a teacher!
THANK YOU FOR THIS AWESOMENESS EXPLANATION!
Edit:
OMG its the same guy who wrote the guide o.o
Happy to help!
Topic archived. No new replies allowed.