2011-02-10 35 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; 
} 

Được hiển thị ở trên là lớp cơ sở của tôi, một biến thành viên được bảo vệ, một trình thiết lập.Vấn đề thừa kế mẫu đơn giản 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 
} 

Đây là lớp con đầu tiên của tôi. Đối với một số lý do, truy cập vào biến thành viên được bảo vệ trực tiếp là không làm việc mặc dù tôi tin rằng nó nên. Tuy nhiên, truy cập vào setter hoạt động tốt. Tôi là một noob với C + +, tôi chắc rằng tôi đang thiếu một cái gì đó hiển nhiên.

+0

Tính năng này có hoạt động nếu bạn viết dữ liệu này-> data = d ;? –

+0

Bạn có thể vui lòng cụ thể hơn về ý nghĩa của nó "không hoạt động" không? Bạn đang nhận được một lỗi biên dịch (và nếu như vậy, cái nào), hoặc nó không có gì trong thời gian chạy hoặc những gì? –

+0

@Michael có, nó có. một cách tự nhiên. – jakev

Trả lời

8

Lý do khiến điều này không hoạt động là một điều không minh bạch trong cách các mẫu C++ làm độ phân giải tên. Đặc biệt, nếu bạn có một lớp mẫu thừa kế từ một lớp khác phụ thuộc vào kiểu mẫu (như bạn đang làm trong trường hợp này), bạn không thể truy cập trực tiếp vào các thành viên của lớp cơ sở đó mà không đưa ra trình biên dịch nhìn. Đây là nguyên nhân gây ra lỗi mà bạn đang gặp phải.

Để khắc phục điều này, bạn có thể viết lại constructor của bạn như

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

Bây giờ trình biên dịch biết rằng data phải bằng cách nào đó là thành viên của aclass<T>, nó có thể tìm thấy những gì nó đang tìm kiếm.

Điều thú vị là bạn cũng sẽ gặp phải lỗi trên dòng trước đó vì lý do tương tự. Tôi không chắc tại sao nó lại quyết định biên dịch. Để sửa lỗi này, bạn có thể làm điều này:

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

Ngoài ra, bạn có thể thêm một tuyên bố using nói với trình biên dịch rằng aclass kế thừa phương pháp setData từ lớp cha của nó. Trong khai báo lớp, cân nhắc việc thêm dòng này:

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

     using baseclass<T>::setData; 
}; 

Giống như this-> cho các thành viên dữ liệu, thủ thuật này làm cho nó rõ ràng nơi tên setData đến từ và giúp trình biên dịch biết những gì bạn đang nói về.

Hy vọng điều này sẽ hữu ích!

+0

Rất hữu ích, cảm ơn bạn. – jakev

+1

Hàm setData (d) hoạt động vì d phụ thuộc vào tham số mẫu. Do đó nó không được giải quyết cho đến khi T được biết đến. Vào thời điểm đó chúng tôi cũng biết lớp cơ sở thực sự. –

+0

http://www.parashift.com/c++-faq-lite/templates.html#faq-35.19 – jakev