2013-05-29 130 views
5
#include <cstdlib> 
#include <vector> 
#include <iostream> 

using namespace std; 

class CFirstLevel { 
public: 
    CFirstLevel (const string & _name): name (_name) {} 
    // ... 

protected: 

    string name; 

}; 

template <typename T> 
class CSecondLevel: public CFirstLevel { 
public: 

    CSecondLevel (const string & _name): CFirstLevel (_name) {} 

    virtual void PushBack (T) = 0; 
    virtual void Print (int I) {cout << data [I] << endl;} 
    // ... 

protected: 
    vector<T> data; 
}; 

template <typename A> 
class CThirdLevel: public CSecondLevel<A> { 
public: 
    CThirdLevel (const string & _name): CSecondLevel<A> (_name) {} 

    virtual void PushBack (A _value) {data.push_back (_value);} 

}; 


int main (void) { 

    CThirdLevel<int> * pointer = new CThirdLevel<int> ("third"); 
    pointer -> PushBack (111); 

    pointer -> Print (0); 

    return 0; 

} 

編譯器返回錯誤:C++繼承

main.cpp中:在成員函數 '虛擬無效CThirdLevel ::則PushBack(T)':

main.cpp中: 32:37:錯誤:'數據'未在此範圍內聲明

問題在哪裏?有可能使用這個繼承嗎?

+2

HTTP:// WWW。 parashift.com/c++-faq-lite/nondependent-name-lookup-members.html – aschepler

+0

[在C++中使用模板訪問超類的受保護成員]的可能副本(http://stackoverflow.com/questions/4010281/accessing-protected-members-of-superclass-in-c-with-templates) – jogojapan

回答

6

問題出在CThirdLevel。該字段data無法從CSecondLevel解決。你可以通過改變

virtual void PushBack (A _value) {data.push_back (_value);} 

解決這

virtual void PushBack (A _value) {CSecondLevel<A>::data.push_back (_value);} 
+5

或者'this - > data.push_back(_value);' – aschepler

+1

原因是C++的'兩階段名稱查找',其中模板中的名稱是依賴的或非依賴的(在模板參數上)。你需要'數據'被分類爲依賴,但沒有'this->'或'CSecondLevel ::'它被歸類爲非依賴。請注意,並非所有編譯器都能正確執行兩階段查找;特別是VC++被稱爲寬鬆。 – bames53

2

正如馬克建議,使用

virtual void PushBack (A _value) { CSecondLevel<A>::data.push_back (_value); } 

或者,你可以做

virtual void PushBack (A _value) { this->data.push_back (_value); } 
+0

'這種技術更多[DRY](http://www.artima.com/intv/dryP.html) – Yakk