Reputation: 744
I have main.cpp
, MyClass.cpp
and MyClass.h
files.
main.cpp
#include <iostream>
#include "MyClass.h"
int main(){
MyClass foo(123);
std::cout << foo.getNumber();
}
MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass
{
public:
MyClass(int n);
int getNumber();
private:
int fav_number;
};
#endif // MYCLASS_H
MyClass.cpp
#include "MyClass.h"
MyClass::MyClass(int n) {
fav_number = n;
}
MyClass::getNumber(){
return fav_number;
}
Now this program compiles and works fine as a project in CodeBlocks, but if I try to compile main seperately (not in a project) I get undefined reference to MyClass::MyClass(int)
. I think it is because in MyClass.h
there is no body for the functions as they're in the cpp
file.
So my question is: how does this program compile as a project even though MyClass.cpp
isn't included anywhere in the main or the header?
Upvotes: 2
Views: 856
Reputation: 385144
You tell it to.
When using an IDE, the list of files in the "project" determines what list of filenames the IDE sends to the compiler, in a build command.
When invoking the build command manually, you have to do that yourself.
For example:
g++ -o myprogram main.cpp MyClass.cpp
Or:
g++ -c main.cpp
g++ -c MyClass.cpp
g++ -o myprogram main.o MyClass.o
Obviously add other flags as needed (include paths etc).
Upvotes: 2
Reputation: 95
From a terminal console you must pass to the compiler g++ as argument all the files *.cpp which main depends on otherwise you will have an error as follows:
$ g++ main.cpp
/tmp/ccDTbMs5.o: In function `main':
main.cpp:(.text+0x15): undefined reference to `MyClass::MyClass(int)'
main.cpp:(.text+0x21): undefined reference to `MyClass::getNumber()'
collect2: error: ld returned 1 exit status
As you can see the compiler is trying to look for object code that is not found. When you compile main.cpp along with all the cpp files corresponding to the includes on your main. In this manner it will work for you as follows:
$ g++ main.cpp MyClass.cpp -o myprogram
$
$ ./myprogram
123
Option -o change the output program to "myprogram".
More complex situations can be treat using builders such as "Makefile".
In case you do not have the implementation files .cpp for each of your header files .h , you should have instead the binary object code. This should be passed to the g++ accordanly.
$ g++ -c MyClass.cpp
$ g++ -c main.cpp
The previous lines creates MyClass.o and main.o. Notice that the -c is passed to the compiler to indicate that only compilation will be done. Now you can pass the objects to the compiler as follows linking all of then together:
$ g++ -o prog MyClass.o main.o
$ ./prog
123
Upvotes: -1
Reputation: 1374
When you add your cpp file to IDE it adds it to compile sources. Depends on your IDE, for example XCode has section compile sources:
If you compile in console with g++, you need to type in console:
g++ main.cpp MyClass.cpp
This means which source files to compile, after that linker should link their main.o MyClass.o files. IDE just do all this stuff by himself.
Upvotes: 4
Reputation: 95
On MyClass.cpp you've forgotten return type specified on its header MyClass.h as follows
int MyClass::getNumber(){
return fav_number;
}
Upvotes: -1
Reputation:
You compile each .cpp
file independently (indeed, if you look at your compiler output, you should see main.o
and MyClass.o
). The header files simply tell the code that the definitions exist somewhere and after compiling, a linker is used to "link" the two .o
files together. It is during the linking stage that the definitions are resolved, so when main.o
refers to code in MyClass.o
, the linker is what puts these together.
CodeBlocks hides this from you, but its calling out to your compiler and linker to do this. (Actually, if you call gcc
with all of your .cpp
files, it will call the linker for you too, but this is simply a convenience and you can do it in multiple steps too. If you are using gcc
to compile, your linker is usually ld
)
Upvotes: 2