2011-02-10 90 views
5
template <class T> 
class baseclass{ 
protected: 
    T data; 
public: 
    baseclass(){}; 
    void setData(T d); 
}; 

template<class T> 
void baseclass<T>::setT(T d){ 
    data = d; 
} 

上面顯示的是我的基類,一個受保護的成員變量,一個setter。簡單模板繼承問題C++

template <class T> 
class aclass : public baseclass<T> 
{ 
    public: 
     aclass(T d); 
}; 

template<class T> 
aclass<T>::aclass(T d){ 
    setData(d); <---WORKS 
    data = d; <---DOESN'T WORK 
} 

現在這是我的第一個子類。出於某種原因,直接訪問受保護的成員變量不起作用,儘管我相信它應該。但是,訪問setter工作正常。我是C++的noob,我確定我錯過了一些明顯的東西。

+0

如果你寫這個 - > data = d ;? – 2011-02-10 06:28:01

+0

您能否更具體地表示「不起作用」?你是否得到了一個編譯器錯誤(如果是這樣,哪一個),或者它在運行時什麼都不做? – 2011-02-10 06:30:38

回答

8

的原因,這並不工作在C++模板名稱解析的方式怪癖。特別是,如果您有一個模板類繼承自另一個依賴於模板類型的類(就像您在這種情況下做的那樣),您無法直接訪問該基類的成員,而無需向編譯器提供關於何處的提示看。這是你得到錯誤的原因。

爲了解決這個問題,你可以重寫你的構造函數

template<class T> 
aclass<T>::aclass(T d){ 
    setData(d); 
    this->data = d; 
} 

現在,編譯器知道data必須以某種方式的aclass<T>一員,它可以找到它的尋找。

有趣的是,你也應該因爲同樣的原因在上一行出現錯誤。我不確定它爲什麼決定編譯。爲了解決這個問題,你可以這樣做:

template<class T> 
aclass<T>::aclass(T d){ 
    this->setData(d); 
    this->data = d; 
} 

或者,你可以添加一個using聲明告訴aclass繼承其父類setData方法的編譯程序。在類的聲明,可以考慮加入這一行:

template <class T> 
class aclass : public baseclass<T> 
{ 
    public: 
     aclass(T d); 

     using baseclass<T>::setData; 
}; 

this->數據成員,這一招使得它毫不含糊其中名稱setData來自和幫助編譯器知道你在說什麼。

希望這會有所幫助!