Class Blueprint in C++

#programming #cpp

This note stems from the question I asked myself when working on Outpost Zero

Why must I declare functions within header files as inline (which is of course, to prevent ODR violations), but not do the same for classes?
Why is it that only the functions get inlined?

Compiler, linker and class blueprints

When you write a function, the compiler turns it into machine code — actual CPU instructions. Each compiled file (translation unit) produces an object file containing symbols for every function and global variable it defines.
When the linker runs, it combines all these object files, matches function calls to definitions, and assembles one unified executable.

That’s why defining the same function body in multiple .cpp files causes a multiple definition error — every file contributes its own copy of that symbol, and the linker doesn’t know which one to keep.
The inline keyword exists to solve this by saying: All these definitions are the same, use any one.

A class, on the other hand, generates no machine code by itself. It’s just a type description — a compile-time layout telling the compiler how objects of that class will look in memory and which functions belong to it.
Only when you define or call a method does actual code get generated. The class itself is more like a blueprint: all instances share the same plan, but the blueprint doesn’t occupy any runtime space.

When we define a function inside a class, we actually make a completely independent function with the same name (the address for which is handled by the compiler), and it looks something like this (if we call p.foo(arg1, arg2))

<type> foo(&p, arg1, arg2)

it basically includes an implicit pointer to the object of the class that the function was called up.

So:

The linker only worries about entities. Blueprints don’t exist at runtime, so including the same class definition across multiple .cpp files is perfectly safe.

Powered by Forestry.md