2013-05-29 7 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; 

} 

compilatore errore restituito:C++ successione di oggetti del modello (G ++ compilatore)

main.cpp: In funzione membro 'virtuale vuoto CThirdLevel :: PUSHBACK (T)':

main.cpp: 32:37: errore: "data" non è stato dichiarato in questo ambito

Dove è un problema? È possibile usare questa eredità?

+2

http: // www. parashift.com/c++-faq-lite/nondependent-name-lookup-members.html – aschepler

+0

possibile duplicato di [accesso ai membri protetti della superclasse in C++ con i modelli] (http://stackoverflow.com/questions/4010281/accessori-membri protetti-di-superclass-in-c-con-templati) – jogojapan

risposta

6

Il problema è in CThirdLevel. Il campo data non può essere risolto da CSecondLevel. È possibile risolvere questo problema modificando

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

a

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

O 'questo -> data.push_back (_value); ' – aschepler

+1

La ragione di ciò è la 'ricerca del nome in due fasi' di C++, dove i nomi nei modelli sono dipendenti o non dipendenti (sui parametri del modello). Hai bisogno di 'data' per essere classificato come dipendente, ma senza' this-> 'o' CSecondLevel :: 'viene classificato come non dipendente. Si noti che non tutti i compilatori eseguono correttamente la ricerca in due fasi; In particolare, VC++ è noto per essere lassista. – bames53

2

Come Marc suggerito, utilizzare

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

In alternativa, si potrebbe fare

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

La tecnica 'this' è più [DRY] (http://www.artima.com/intv/dryP.html) – Yakk

Problemi correlati