14

I want to include implementation of a function inside an .h file.

I know I would rather separate declaration and implementation to .h and .c file accordingly, this is not a part of my question.

When I implement the function inside the class, I receive no errors:

class Foo { public: // Class constructor Foo() { } }; 

When I implement the function outside the class (still in the .h file):

class Foo { public: // Class constructor Foo(); }; Foo::Foo() { } 

I receive the following error: multiple definition of Foo:Foo()

Can someone explain me the logic behind this? Thanks.

0

2 Answers 2

26

This is because when you define the function in the class definition, the method is treated as an inline function. Which can be included in multiple source files, be compiled and linked together and still have the linker not complain about multiple definitions.

But when you define the constructor outside the class, #include it in multiple source files, compile them together and then link them. You get multiple definitions for the same function.

Remember that #includeing a file is essentially a copy paste of that file into the file that #includes it. So every time that file is included, you get a definition for the function in that source file. And then when you compile and link multiple such sources together you get multiple definitions for the same non-inline function.


For more see on inline, see http://en.cppreference.com/w/cpp/language/inline. The examples section has a good chunk of code that should help.


You can also explicitly mark the definition outside the class to be inline like @StoryTeller correctly noted.

Sign up to request clarification or add additional context in comments.

3 Comments

inline in C has different semantics to C++, I don't think that other question is relevant. The code in the linked question may fail to compile in C but is correct and good practice in C++
@M.M updated my answer! Although just out of curiosity, what are the differences in semantics?
15

Mark it inline

class Foo { public: // Class constructor inline Foo(); }; inline Foo::Foo() { } 

Like Curious said, an in-class definition is implicitly inline. But if you define it outside the class, in a header, you must add the specifier explicitly.

The inline specifier is very important for correct linkage in cases like this. It allows the same function to exist in multiple translation units, so long as it's the exact same function body. A case that often occurs with functions defined in a header file.

4 Comments

What is inline required for in C++ then at all? wouldn't include guards be totally sufficient?
@dhein - Include guards protect you from double inclusion in the same translation unit. But headers are meant to be included freely in separate translation units. When the resulting object files are linked, you'd get an ODR violation, unless the compiler was informed it's an inline function.
Oh, wait... I got it! Since which C++ this is included in the standard? I remember having encountered such a problem in a private project some years ago.... My teacher explained me to use prototypes for the functions to make my project work again. That helped for some time but just made the mess worse later on and I just dropped the project. I feel like digging it up again to see if this would have solved it back then.
@dhein - Since C++98. Originally also "a hint to the compiler" that the functions entire body should be inlined, but that is now deprecated. The linkage ramifications remain however, and are very important.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.