including header causes error, but including cpp does not

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
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.
I'd recommend using an IDE. Compiling from the commandline and writing makefiles by hand are borderline masochism.
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
> 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.