为何链接阶段函数会触发重定义错误,而类却不会?是否类似inline函数?
Great question! Let's unpack this behavior and how it relates to inline functions.
First: Why Non-Inline Functions in Headers Break Things
When you put a non-inline function definition (like void hello(){}) in a header and include it in multiple .cpp files, each translation unit (.cpp file plus its included headers) gets its own copy of that function's definition.
The C++ One Definition Rule (ODR) states that non-inline functions must have exactly one definition across the entire program. When the linker tries to combine all the object files, it sees multiple identical hello() definitions and throws a "multiple definition" error.
Your example makes this clear:
// A.h void hello(){} // Non-inline function definition // A.cpp #include "A.h" // Gets a copy of hello() // main.cpp #include "A.h" // Gets another copy of hello()
Linking these two .cpp files will trigger a redefinition error because there are two hello() implementations.
Why Class Definitions Are Safe
Classes are treated differently under the ODR. The rule allows a class to be defined in multiple translation units as long as all definitions are identical.
When you include a class definition (like class A{}) in multiple .cpp files, each translation unit gets its own copy of the class's type information—but since classes don't generate executable code on their own (only their member functions do, if defined inline or in a .cpp), the linker doesn't see conflicting "symbols" for the class itself.
Your class example works because of this:
// A.h class A{}; // Class definition // A.cpp #include "A.h" // Gets a copy of class A's definition // main.cpp #include "A.h" // Gets another identical copy of class A's definition
The linker doesn't flag this as an error because the class definitions are identical, and the ODR explicitly permits this scenario.
How This Compares to Inline Functions
You're right to draw a parallel to inline functions—they share a key ODR property with classes: both allow multiple identical definitions across translation units.
For inline functions, the ODR relaxes the single-definition rule: if you mark a function as inline, you can define it in a header and include it in multiple .cpp files without redefinition errors. The compiler either expands the inline function at each call site (avoiding a separate definition) or ensures only one shared copy is used across the program.
That said, the similarity ends there:
- Classes are type definitions—they describe a structure, not executable code.
- Inline functions are executable code—the ODR relaxation exists to let you define them in headers for convenience, while avoiding linker conflicts.
Summary
To wrap up:
- Non-inline functions in headers violate the ODR's single-definition rule, causing linker errors.
- Class definitions are allowed in multiple translation units (as long as identical) because they're type information, not conflicting executable symbols.
- The ODR treatment of classes is similar to inline functions in that multiple identical definitions are permitted, but their underlying reasons differ.
内容的提问来源于stack exchange,提问作者Rick

