c++: class declaration and definition separated inside header causes Duplicate Symbol
I usually only have the definitions of my classes inside a header if they are template classes.- If this is the case, i still like to split declaration and definition inside the header like that:
template<class T>
class Foo
{
public:
Foo();
void fooFunc();
};
template<class T>
Foo<T>::Foo()
{
}
template<class T>
void Foo<T>::fooFunc()
{
}
that code also com开发者_运维问答piles. But If I remove the template:
class Foo
{
public:
Foo();
void fooFunc();
};
Foo::Foo()
{
}
void Foo::fooFunc()
{
}
i get a duplicate symbol error for Foos functions. I was very sure that this should work and am very surprised that it does not. Is this expected behaviour? If I add an inline before the definition it works too.
Yes, it's expected behavior.
Inline functions are meant to be compiled separately into each call site so duplication is no problem. For template functions, the compiler flags them in the object file such that the linker will basically ignore duplicates, since it can be difficult to predict where the template will or will not be instantiated.
But conventional functions are expected to be defined exactly once. If you define one in a header file, it gets compiled into each translation unit that includes the header, leading to a "duplicate symbol" error at link time if you have more than one object file containing a copy of the function.
I guess the linker knows the difference between a class that's defined in more than one translation unit and a templated class that's defined in more than one translation unit. For the former, it generates a duplicate symbol error, for the latter, it treats the two instances as the same thing and only uses one of them.
精彩评论