Reputation: 366
I have a hpp file like this:
#ifndef __MYLIB_H
#define __MYLIB_H
class A {
public:
void func1();
void func2();
};
void A::func1() {
// maybe do something
}
#endif
There is a corresponding cpp file which has the implementation of func2. The header file is included by other files in the project (and those are included by yet more files). When I try to build this, I get "multiple definition" linker errors for func1
. Why should that happen? Since I've protected the header file with the #ifndef
, I did not expect the error.
If I add the keyword inline
to the definition of func1
, then everything is fine. So if I don't care about a function being inlined and I don't want to have the definition in the class body, I cannot include the definition it in the hpp file? If someone can explain the what's going on here, it'll be very helpful. I'm using GCC 6.
Upvotes: 1
Views: 158
Reputation: 726479
Recall that the content of the entire header, along with any files that it may include, is virtually "copy-pasted" into each translation unit* that includes the header at the point of inclusion.
That is why the effect of including the header in multiple CPP files is the same as if you literally copy-pasted function definition into each CPP, i.e. it is the same as if you wrote multiple identical definitions of the same member-function.
The problem is solved by declaring the function inline
, because C++ allows multiple definitions of inline functions, as long as they are identical to each other. Moving the body of the function into the declaration of the class also works, because such functions are automatically considered inline
.
* In this context, "translation unit" is a fancy name for your CPP file.
Upvotes: 2
Reputation: 1403
The problem is that you are redefining func1
in every file.
The #include
directive is a very simple command that just pastes the contents of the header file into the location specified.
The result of this is that each time you #include
your header you are "redefining" func1
in that file.
Upvotes: 2
Reputation: 211540
Implementations generally go in the associated .cpp
files. Putting them in the headers is problematic. inline
is a hack to get around this you probably don't want to use since it stamps out that code everywhere it appears, resulting in wild duplication.
Remember, #include
is quite like pasting that file in the code right where that directive appears. Having more than one implementation for a function is incorrect, that's why they're split out between header for signature purposes, so it's understood how to use those functions correctly, and implementation for the actual code.
Upvotes: 0