The following is a simple example for separate compilation:
// mod.cpp
#include <cstdio>
class MyModule {
public:
void print_msg();
};
void MyModule::print_msg() {
printf("hello from module\n");
}
// main.cpp
class MyModule {
public:
void print_msg();
};
int main() {
MyModule a;
a.print_msg();
}
We can compile and run it with
g++ main.cpp -c -o main.o
g++ mod.cpp -c -o mod.o
g++ main.o mod.o -o main
./main
The above works fine, but if I move the definition of MyModule::print_msg
inside the class:
// mod.cpp
#include <cstdio>
class MyModule {
public:
void print_msg() { printf("hello from module\n"); }
};
I get an 'undefined reference' error for compiling main
:
g++ main.cpp -c -o main.o # OK
g++ mod.cpp -c -o mod.o # OK
g++ main.o mod.o -o main # undefined reference error
/usr/bin/ld: main.o: in function `main':
main.cpp:(.text+0x23): undefined reference to `MyModule::print_msg()'
collect2: error: ld returned 1 exit status
I know that the former is the standard way and the class definition should go to a header file, but I wonder why the second method doesn't work.
Functions defined inside the class are implicitly inline. C++ requires:
The definition of an inline function [or variable (since C++17)] must be reachable in the translation unit where it is accessed.
Since you only defined it in mod.cpp
, no definition is reachable in main.cpp
, and compilation fails.
Typically, you'd put the definition of the class, and the definition of all functions defined within it, in a header file to be included by all users of the class. The functions defined outside the class then go in a .cpp
file. That way a single consistent definition of all the inline functions is available to all users of the class, and you're not repeating the definition of the class in each .cpp
file manually.