Reputation: 85
I would like to know the exact compiler behavior that produces this error.
Have a look at this code.
class Base_class
{
public:
Base_class();
};
Base_class::Base_class()
{
//Here it says multiple definitions (If I define the contructor outside)
//If I define this inside class no error
//Or if I make the base class templated no error
//Also if this is in .cpp it works.
}
template<typename T>
class Temp_derived_class:Base_class
{
public:
Temp_derived_class();
int *i;
};
template<typename T>
Temp_derived_class<T>::Temp_derived_class()
{
i = new int[5];
}
Here it says multiple definitions (If I define the contructor outside) If I define this inside class no error Or if I make the base class templated no error Also if this is in .cpp it works.
Cheers, CB
Upvotes: 0
Views: 1503
Reputation: 254431
All used functions must have exactly one definition in the program, or be inline. By putting a non-inline definition in a header, you usually end up with multiple definitions, which is an error.
You can either:
inline
, orFunction templates, and member functions defined inside the class definition, are implicitly inline, which is why there isn't a similar problem with the class template's constructor.
Upvotes: 4
Reputation: 55395
When you put a function definition in a header, every translation unit that includes that header gets its own definition of the function. The One Definition Rule says that every name can have at most one definition in the whole program.
There are exceptions, though. In case of functions, there can be more definitions if the functions is marked inline
and all definitions consist of same sequence of tokens. Member functions defined inside the class are implicitly inline and so are templates.
So, in addition to the workaround you've already found, you can also mark the constructor inline:
inline Base_class::Base_class()
{
}
Upvotes: 2
Reputation: 21003
A template class with a non-template base class should be written inline to avoid compiler confusion. All the core logic should be in the base class and the template is just there to make casting easier.
i.e.
template<typename T>
class Temp_derived_class:Base_class
{
public:
Temp_derived_class()
{
i = new int[5];
}
int *i;
};
Upvotes: 0