2010-11-17 94 views
2

有這個基本的層次:多態顯式模板實例

// header 

class Base 
{ 
    virtual void method() { } 
    virtual ~method() { } 
}; 

class Subclass : Base 
{ 
    virtual void method() { } 
    virtual ~method() { } 
}; 

我想有兩個明顯的變化子類基地(無需提供子類,如果可能的兩種實現),因此它已建議使用顯式模板實例:

// header 

class Base 
{ 
    virtual void method() { } 
    virtual ~method() { } 
}; 

class Base1 : public Base { }; 
class Base2 : public Base { }; 

template <typename T>  
class Subclass : public T 
{ 
    virtual void method(); 
    virtual ~method() { } 
}; 

// cpp 

template <typename T> 
void Subclass<T>::method() 
{ 
} 

template class Subclass<Base1>; 
template class Subclass<Base2>; 

我得到這個錯誤:

there are no arguments to 'method' that depend on a template parameter, so a declaration of 'method' must be available

這是正確的方法嗎?我顯然必須模板Base才能編譯,但是用什麼?

+0

不要忘記虛擬析構函數。就像金錢和性不同,你需要去尋求它,否則你就不會得到它。 – wilhelmtell 2010-11-17 16:22:51

回答

0

問題和解決方案的小結:

爲了從模板化基類中使用的方法要求要麼使用模板參數:

T::method(); 

或者簡單地使用「this」以允許在沒有明確知道模板參數的情況下找到它:

this->method(); 

感謝那些指出我尋找這個解決方案的人,我並沒有意識到這一點。也希望指出將模板放在cpp文件中沒有問題。

2

您應該將模板類和函數的定義放在頭文件中(它必須對誰使用它們是可見的)。

只能聲明完整的特化(並定義代碼在哪裏沒有可見性)。

此外,如果你要定義一個類模板出來的類的函數(像你一樣),你必須聲明爲模板:

template< typename T > 
void Class<T>::method() 
{ 
} 

無論如何,如果我沒有記錯,當你使用函數method時,引用的錯誤是由你繼承的類型名提供的(我認爲你沒有發佈產生錯誤的代碼段):它只能被找到當模板實際被實例化時,您需要明確地說它取決於模板參數。

呼叫method以這種方式:

T::method(); 
+0

我理想情況下不喜歡將定義放入頭文件中,因爲有很多計算,並且如果我可以避免它,編譯時間就會增加? – Dan 2010-11-17 16:56:45

+0

所以沒有辦法使用多態性調用method()而不必知道基類是什麼? – Dan 2010-11-17 17:00:21

+2

在這個時候希望在標題之外有模板,這真是不幸。試着與你的編譯器廠商談談爲模板實現「導出」......祝你好運。如果不知道底座在定義底座的派生內部,則無法在底座中調用method()。如果你從子類中移除方法(),它會起作用。否則,你必須使用答案中提到的語法。 – 2010-11-17 17:38:54