including header causes error, but including cpp does not

Dec 29, 2012 at 7:52am
in main.cpp if i include the header files, it raises the error

1
2
3
4
5
6
7
metulburr@ubuntu:~/Documents/cplusplus/composition$ g++ main.cpp -o main
/tmp/ccb7S83C.o: In function `main':
main.cpp:(.text+0x20): undefined reference to `Birthday::Birthday(int, int, int)'
main.cpp:(.text+0x58): undefined reference to `People::People(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Birthday)'
main.cpp:(.text+0x7c): undefined reference to `People::printinfo()'
collect2: ld returned 1 exit status
metulburr@ubuntu:~/Documents/cplusplus/composition$ 


files in same directory:
1
2
3
metulburr@ubuntu:~/Documents/cplusplus/composition$ ls
Birthday.cpp  Birthday.h  main.cpp  People.cpp  People.h
metulburr@ubuntu:~/Documents/cplusplus/composition$ 


but if i include the cpp files, it compiles and works. On the other hand, as i googled around for the reason the only thing i could find was to never include a cpp file as it compiles twice. So what would cause the header files to cause compiles errors and not cpp files? And what might i do to fix it?


main.cpp
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include "Birthday.h"
#include "People.h"
using namespace std;

int main(){
	Birthday birthobj(2,27,1987);
	People pers1("Micah Robert", birthobj);
	pers1.printinfo();
}


Birthday.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef BIRTHDAY_H
#define BIRTHDAY_H

class Birthday{
	public:
		Birthday(int m, int d, int y);
		void printdate();
	private:
		int month;
		int day;
		int year;
};

#endif 


Birthday.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "Birthday.h"
#include <iostream>
using namespace std;

Birthday::Birthday(int m, int d, int y){
	month = m;
	day = d;
	year = y;
	
}

void Birthday::printdate(){
	cout << month << "/" << day << "/" << year << endl;
}


People.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef PEOPLE_H
#define PEOPLE_H

#include <string>
#include "Birthday.h"
using namespace std;

class People{
	public:
		People(string x, Birthday y);
		void printinfo();
	private:
		string name;
		Birthday dateofbirth; //pass in obj to People class 
	
};

#endif 


People.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "People.h"
#include "Birthday.h"
#include <iostream>
using namespace std;

People::People(string x, Birthday y)
: name(x), dateofbirth(y)
	{
		
	}
		
void People::printinfo(){
	cout << name << "was born on ";
	dateofbirth.printdate();
}



an example of changing .h to .cpp:
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
metulburr@ubuntu:~/Documents/cplusplus/composition$ ls
Birthday.cpp  Birthday.h  main.cpp  People.cpp  People.h
metulburr@ubuntu:~/Documents/cplusplus/composition$ sudo vim main.cpp
[sudo] password for metulburr: 
metulburr@ubuntu:~/Documents/cplusplus/composition$ cat main.cpp
#include <iostream>
#include "Birthday.cpp"
#include "People.cpp"
using namespace std;

int main(){
	Birthday birthobj(2,27,1987);
	People pers1("Micah Robert", birthobj);
	pers1.printinfo();
}
metulburr@ubuntu:~/Documents/cplusplus/composition$ g++ main.cpp -o main
metulburr@ubuntu:~/Documents/cplusplus/composition$ ./main
Micah Robertwas born on 2/27/1987
metulburr@ubuntu:~/Documents/cplusplus/composition$ sudo rm main
metulburr@ubuntu:~/Documents/cplusplus/composition$ ls
Birthday.cpp  Birthday.h  main.cpp  People.cpp  People.h
metulburr@ubuntu:~/Documents/cplusplus/composition$ sudo vim main.cpp
metulburr@ubuntu:~/Documents/cplusplus/composition$ cat main.cpp
#include <iostream>
#include "Birthday.h"
#include "People.h"
using namespace std;

int main(){
	Birthday birthobj(2,27,1987);
	People pers1("Micah Robert", birthobj);
	pers1.printinfo();
}
metulburr@ubuntu:~/Documents/cplusplus/composition$ g++ main.cpp -o main
/tmp/ccSoEFfm.o: In function `main':
main.cpp:(.text+0x20): undefined reference to `Birthday::Birthday(int, int, int)'
main.cpp:(.text+0x58): undefined reference to `People::People(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Birthday)'
main.cpp:(.text+0x7c): undefined reference to `People::printinfo()'
collect2: ld returned 1 exit status
metulburr@ubuntu:~/Documents/cplusplus/composition$

Last edited on Dec 29, 2012 at 8:16am
Dec 29, 2012 at 10:22am
ok i figured it out.

i didnt know you had to compile each cpp beforehand. Which in turn eventually led me to using a makefile.

which consisted of:
1
2
3
4
5
6
7
8
9
10
main : main.o People.o Birthday.o
	g++ -o main main.o People.o Birthday.o
main.o: main.cpp People.h Birthday.h
	g++ -c main.cpp
Birthday.o: Birthday.cpp Birthday.h
	g++ -c Birthday.cpp
People.o: People.cpp People.h
	g++ -c People.cpp
clean:
	&nbps    rm *.o main


which im not really sure what is going on and the process about it.
Dec 29, 2012 at 4:36pm
I'd recommend using an IDE. Compiling from the commandline and writing makefiles by hand are borderline masochism.
Dec 29, 2012 at 4:49pm
well im glad i accidentally stumbled on it, as i like to know whats going on under the hood and ended up learning more about it.

Does IDE's make a makefile? What if you wanted to distribute the source instead of pre compiling?
Last edited on Dec 29, 2012 at 4:58pm
Dec 29, 2012 at 5:56pm
> What if you wanted to distribute the source instead of pre compiling?

The three steps involved:
./configure && make && make install

For example, with the GNU toolchain: http://www.airs.com/ian/configure/

Essential knowledge for any serious programmer.
Topic archived. No new replies allowed.