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

} 

biên dịch lại lỗi:C++ thừa kế của mẫu vật (G ++)

main.cpp: Trong chức năng thành viên 'virtual void CThirdLevel :: PUSHBACK (T):

main.cpp: 32:37: lỗi: 'dữ liệu' không được khai báo trong phạm vi này

Trường hợp xảy ra sự cố? Có thể sử dụng thừa kế này?

+2

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

+0

có thể trùng lặp của [truy cập các thành viên được bảo vệ của siêu lớp trong C++ với các mẫu] (http://stackoverflow.com/questions/4010281/accessing-protected-members-of-superclass-in-c-with-templates) – jogojapan

Trả lời

6

Sự cố xảy ra ở CThirdLevel. Không thể giải quyết trường data từ CSecondLevel. Bạn có thể giải quyết việc này bằng cách thay đổi

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

để

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

Hoặc 'điều này -> data.push_back (_value); ' – aschepler

+1

Lý do cho điều này là 'tra cứu tên hai pha' của C++, trong đó các tên trong các mẫu là phụ thuộc hoặc không phụ thuộc (trên các tham số mẫu). Bạn cần 'dữ liệu' để được phân loại là phụ thuộc, nhưng không có' this-> 'hoặc' CSecondLevel :: 'nó được phân loại là không phụ thuộc. Lưu ý rằng không phải tất cả trình biên dịch đều tra cứu hai pha đúng cách; VC + + nói riêng được biết đến là lax. – bames53

2

Như Marc đề nghị, sử dụng

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

Ngoài ra, bạn có thể làm

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

Kỹ thuật 'này' hơn [DRY] (http://www.artima.com/intv/dryP.html) – Yakk