Can't I use a header file in another?

Hey Guys!

I'm using two headers in my program.

One is called Screen_output.h and Controls.h

In my function list of Screen_output.h I want to use a function created in a class within Controls.h

I only add #include "Controls.h" in the library of Screen_output.h and try to compile and it already throws out a lot of errors.

Isn't there a workaround to actually use them!?

1
2
3
4
5
6
7
8
  #include <iostream>
#include <fstream>
#include <string>
#include "Controls.h"

#ifndef Screen_output_h   
#define Screen_output_h  
...
Including a header in another header isn't inherently bad; after all, you were doing it with the standard headers without problems. You're going to need to give some more detail. What do those headers look like, and what are the errors?
This is my Screen_output.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <iostream>
#include <fstream>
#include <string>
#include "Controls.h"

#ifndef Screen_output_h   
#define Screen_output_h  

using namespace std;

class Screen_output
{
	int field_size;
	const char * field_name;
	public:
	int move();
	void create_field(const char*);
	void title(const char*);
	void field();
	char * file_to_array();
} draw;


int Screen_output::move()
{
	char x;
	cin >> x;
	if(x == 'w')
		return 1;
	else
		return 0;

}

void Screen_output::create_field(const char* file_n)
{
	field_name = file_n;
}
	
void Screen_output::title(const char* file_n)			
{
	string text_line;
	
	ifstream file (file_n);
		if (file.is_open()) 
		{
			while(getline(file, text_line))
			{
			cout << text_line << endl;	
			}
			file.close();
		}
}

void Screen_output::field()
{
	
	char * array = file_to_array();
	
	array[939+move()] = 'X';	//create Player Spot X
	
	for (int i = 0; i < field_size-1; i++)
	{
		
		cout << array[i];
	}
}

char * Screen_output::file_to_array()
{	
	field_size = 1799;
	char * array = new char[field_size];
	int position = 0;


	ifstream file (field_name);
		if (file.is_open()) 
		{
			while(!file.eof())
			{
				file.get(array[position]);
				position++;
			}
			file.close();
		}
	
	return array;
}

#endif 


And this is my Controls.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

#ifndef Controls_h   
#define Controls_h


class Controls
{
	public:
	int choose();
} ctrl;


int Controls::choose()
{
	int x;
	string line;
	
	std::cout << std::endl;
	std::cout << "Gebe deine Auswahl ein: ";
	getline(cin, line);
	stringstream(line) >> x;
	
	return x;
}

#endif 



ERROR OUTPUT:

http://my.jetscreenshot.com/13371/20140314-qw8r-72kb
In your 'Controls' file, you have forgotten to scope std::string, std::getline, std::cin, std::stringstream. Also, avoid using namespace std; in header files (you have it there on Screen_output.h). Also, you will probably get a 'multiple definitions' error from your definition of ctrl inside Controls.h and draw inside Screen_output.h. Instead, do something like this:
1
2
3
4
5
6
class Controls {
    // ...
};
extern Controls ctrl;

// (Same for 'draw') 

And then make sure to declare 'ctrl' and 'draw' inside a .cpp file (for example, main.cpp):
1
2
3
4
#include "Controls.h"
#include "Screen_output.h"
Controls ctrl;
Screen_output draw;
Well you are right - I actually learned to define them as you wrote above "Controls ctrl;"

How come the main.cpp doesn't drop any error - because I directly used things like "draw.field();" without any definition of Screen_ouput draw;

How come it still worked? My compiler did it itself?


And whats the use of "extern Controls ctrl;"

I didn't read about that in the Classes(I) Chapter of cplusplus.com
Last edited on
I presume you only have one source file?

Basically, when you declare a variable in a header file, every time it is included in a source file the variable is re-declared. This means that when it gets to the linking stage of compilation, the linker will give errors because you have multiple instances of the variable. The 'extern' keyword is a way of getting around that: It basically tells the source file that the variable exists somewhere in the object files for your program. As long as you define the variable (once) somewhere in a source file, the program will find it at the linking stage and everything will work as expected.

Also, you did define Screen_output draw, see line 21 of Screen_output.h.
Ahhhh yea right I added the object name at the end of the class definition ^^ forgot that this will make Screen_output draw; not needed.

Well when I declare a variable in a source file it is declared within the function scope isn't it? So there might not be any problem within the source file later?

Or is it usual that there may be variables declared in a header file outside of any functions (global scope in that case?) - and be used in source files (didn't did that yet) so there might be a error with "headers" variable called -Tester- and the one already declared in the "source" file?
When you declare a variable inside a source file it is in global scope, just like declaring it in a header file. I'm not sure you are entirely understanding what is going on here, so I'll give you an example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Header.hpp
#ifndef __HEADER_HPP_INCLUDED__
#define __HEADER_HPP_INCLUDED__
int val;
void doSomething();

#endif // __HEADER_HPP_INCLUDED__

// dosomething.cpp
#include "Header.hpp"

void doSomething() {
    val = 5;
}



// main.cpp
#include "Header.hpp"
#include <iostream>

int main() {
    doSomething();
    std::cout << val;
    return 0;
}


In this example, you will get an error. This is because all the contents of Header.hpp is just copied straight into the source files, so two copies of 'val' will have been declared: one for 'main.cpp' and one for 'dosomething.cpp'. This is because neither know of the existance of the other value. One way to fix this would be to declare val as extern, saying it is outside that particular source file. If we take what the compiler sees, the two source files would look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// dosomething.cpp
void doSomething();
extern int val;

void doSomething() {
    val = 5;
}



// main.cpp
void doSomething();
extern int val;
/* contents of <iostream> are here */

int main() {
    doSomething();
    std::cout << val;
    return 0;
}


Now, you'll get a different error: Because declaring val extern doesn't actually declare the variable, you have told the linker of the existance of a variable that doesn't actually exist. Therefore, our final program should look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Header.hpp
#ifndef __HEADER_HPP_INCLUDED__
#define __HEADER_HPP_INCLUDED__

void doSomething();
extern int val;

#endif // __HEADER_HPP_INCLUDED__



// doSomething.cpp
#include "Header.hpp"
int val; // declaring 'val' so it exists somewhere

void doSomething() {
    val = 5;
}



// main.cpp
#include "Header.hpp"
#include <iostream>

// don't define 'val' here: otherwise we get our original problem again!

int main() {
    doSomething();
    std::cout << val;
    return 0;
}


Now, if you are only using one source file, this problem wouldn't have occurred. However, it is good to get into the practice of doing things like this with global variables declared in header files, so that you don't add in another source file and suddenly find everything has broken.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
// main.cpp
#include "Header.hpp"
#include <iostream>

// don't define 'val' here: otherwise we get our original problem again!

int main() {
    doSomething();
    std::cout << val;
    return 0;
}



Well ok I get it - still I wonder why the linker doesn't realise that the value "val" in the source is actually extern. Because in main.cpp you didn't declared it but you did in header.hpp. Since it is just declared in that header why should it be copied twice? main.cpp is just calling the variable here - since it isn't declared in main.cpp why does it think there are two variables here if its just "imported" from that header.cpp


You know what I mean? I actually understand issues with copied variables but since main.cpp isn't declaring a "second" variable called "val" I don't really see the issue of "TWO" variables due the copying of one from the header.cpp since there wasn't any one before the copying declared anyway.

Hope I don't make you mad cause I don't get at with your example, too :/
1) Remove line #include "Header.hpp" from every place of your program.
2) Open your Header.hpp, select all, press Ctrl+C, then paste it into the same line where your #include was. See multiple declarations now? That is exacly what include does: copypasting all content from one file into other.
Ha....wow...simple as that as it seems :) thx bro

think the other one tried to explain it just that way - I just thought there would be more "complicated" conditions in those appendings
Topic archived. No new replies allowed.