2013-07-30 34 views
0

我想知道产生此错误的确切编译器行为。具有非模板基类的模板类

看看这段代码。

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]; 
} 

这说多定义(如果我定义外的构造器) 如果我定义这个类里面没有错误 或者,如果我做模板没有错误的基类 此外,如果这是的.cpp它的工作原理。

干杯, CB

+0

它就像使用任何非内联非模板函数一样:如果在头文件中定义它,会出现多个定义错误。这里的模板只是一个分心。 – juanchopanza

回答

0

与非模板基类模板类应该内联写入到避免编译混淆。所有的核心逻辑都应该放在基类中,而模板就在这里让铸造更容易。

template<typename T> 
class Temp_derived_class:Base_class 
{ 
public: 

    Temp_derived_class() 
    { 
     i = new int[5]; 
    } 

    int *i; 
}; 
+1

问题出在*非* -template构造函数。任何函数模板都是隐式内联的,所以在那里没有“编译器混淆”。 –

2

当你把一个函数定义在一个头,这包括报头的每个翻译单元都有自己定义的函数。 One Definition Rule表示每个名字在整个程序中最多只能有一个定义。

虽然也有例外。在功能的情况下,如果功能被标记为inline并且所有定义由相同的标记序列组成,则可以有更多的定义。在类内定义的成员函数是隐式内联的,模板也是。

因此,除了解决方法你已经发现,你还可以标记构造内联:

inline Base_class::Base_class() 
{ 
} 
+1

只是为了强调,非模板是作为基础还是其他用途并不重要。只是该函数是内联的,而内联的一种方法是在'class'内部定义。 – Potatoswatter

4

所有使用功能必须有一个确切的定义,程序,或者是内联。通过在头文件中添加非内联定义,通常会得到多个定义,这是一个错误。

您可以:

  • 声明构造inline,或
  • 移动定义为一个源文件或
  • 移动定义为类定义。

函数模板和类定义中定义的成员函数是隐式内联的,这就是为什么类模板的构造函数没有类似的问题。