2013-07-30 39 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,或
  • 移動定義爲一個源文件或
  • 移動定義爲類定義。

函數模板和類定義中定義的成員函數是隱式內聯的,這就是爲什麼類模板的構造函數沒有類似的問題。