cow boy
cow boy

Reputation: 85

Template class with a non template base class

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

Answers (3)

Mike Seymour
Mike Seymour

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:

  • Declare the constructor inline, or
  • Move the definition into a source file, or
  • Move the definition into the class definition.

Function 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

jrok
jrok

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

bizzehdee
bizzehdee

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

Related Questions