//下面是我自己總結理解的,還在查找依據當中。
1. 類模板 vs 模板類
類模板是模板的一種, 可以在使用時確定類的類型。
類模板不是一個類,不能直接用於生成對象。 Foo f;是錯誤的。
template< class T>
class Foo
{
T tVar;
//...
};
模板類 就是 類模板的一個實例,是一個確定了類型的 具體的類。可以直接生成對象。
Foo<int> 或 Foo<double> 就是兩個Foo的模板類。 可以直接生成對象 Foo<int> fi; Foo<double> fd; 都正確。
2.模板類的派生。 此處模板類也稱為“非依賴型基類”
模板類就是一個具體的類,和一般的類沒有區別,派生時也沒有區別。
class Sun : public Foo<int>
{
//tVal是int
}
class Sun2: public Foo<double>
{
//tVal是double
}
但,當派生類是一個類模板的時候,有一個問題需要注意。在派生類中的非限定類型的查找,會先查找這個非依賴型基類,然后才會查找模板參數列表。
template<typename T>
class Base
{
public:
int basefield;
typedef int T;
};
template<typename T>
class D2:public Base<double>
{
public:
void f() { basefield = 7; }//正常訪問繼承成員
T strange; //T是Base<double>::T,而不是模板參數 。
};
3.類模板的派生。 --派生類也一定是模板
這種情況下,應注意的問題是:非依賴性名稱(即普通成員,跟T類型沒關系的)不會在依賴基類中查找 (注,Windows的VC已經讓這種方式通過編譯了。)
template<typename T>
class Base
{
public:
int basefield;
};
template<typename T>
class D2:public Base<T>
{
public:
void f() { basefield = 7; }//不認識basefield
};
解決方法就是將非受限名稱改為受限名稱。 簡單來說就是顯示的說明basefield是這個類的成員。
1)this->basefield = 7;
2) Base<T>::basefield =7;
但用這種方式的問題是,如果該成員是個虛函數,則失去了多態的性質。
至於為什么明明是父類的成員 卻 在子類中被隱藏了,是因為模板存在特化。特化相當於是另一個類,所以很可能在特化版本中,根本沒有這個成員。
為了防止在繼承特化版本,調用該成員時報錯,就假定不知道 父類中有沒有這個成員,所以需要顯式說明。 具體可以參看<<Effective C++>>條款43.
