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

ऊपर दिखाया गया मेरा बेस क्लास, एक संरक्षित सदस्य चर, एक सेटर है।सरल टेम्पलेट विरासत समस्या सी ++

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 
} 

अब यह मेरा पहला उप-वर्ग है। किसी कारण से, संरक्षित सदस्य चर का उपयोग सीधे काम नहीं कर रहा है हालांकि मुझे विश्वास है कि इसे करना चाहिए। हालांकि, सेटर का उपयोग ठीक काम करता है। मैं सी ++ के साथ एक नोब हूं, मुझे यकीन है कि मुझे कुछ स्पष्ट याद आ रही है।

+0

यदि आप इसे लिखते हैं तो यह काम करता है-> डेटा = डी ;? –

+0

क्या आप कृपया अधिक विशिष्ट हो सकते हैं इसका अर्थ है "काम नहीं करता"? क्या आपको एक कंपाइलर त्रुटि मिल रही है (और यदि हां, तो कौन सा), या यह रनटाइम पर कुछ भी नहीं करता है या क्या? –

+0

@ माइकल हाँ, यह करता है। सहज रूप में। – jakev

उत्तर

8

कारण यह काम नहीं करता है कि सी ++ टेम्पलेट्स नाम संकल्प के तरीके में एक quirk है। विशेष रूप से, यदि आपके पास एक टेम्पलेट क्लास है जो किसी अन्य वर्ग से प्राप्त होती है जो टेम्पलेट प्रकार पर निर्भर करती है (जैसा कि आप इस मामले में कर रहे हैं), तो आप संकलक को बिना किसी संकेत के बताए सीधे उस बेस क्लास के सदस्यों तक नहीं पहुंच सकते देखो। यह आपके द्वारा प्राप्त त्रुटि का कारण है।

इसे ठीक करने के लिए, आप अपने निर्माता के रूप में

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; 
} 

वैकल्पिक रूप से, आप संकलक कि aclass विरासत में अपनी मूल वर्ग से setData विधि बताने के लिए एक using घोषणा जोड़ सकते हैं। ,

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

     using baseclass<T>::setData; 
}; 

डेटा सदस्यों के लिए this-> की तरह इस चाल यह स्पष्ट जहां नाम setData से आता है और मदद करता है संकलक पता है तुम क्या बारे में बात कर रहे हैं बनाता है: वर्ग घोषणा में, इस लाइन को जोड़ने पर विचार।

आशा है कि इससे मदद मिलती है!

+0

बहुत उपयोगी, धन्यवाद। – jakev

+1

सेटडाटा (डी) काम करता है क्योंकि डी टेम्पलेट पैरामीटर पर निर्भर है। इसलिए टी को ज्ञात होने तक इसे हल नहीं किया जाता है। उस समय हम वास्तविक आधार वर्ग भी जानते हैं। –

+0

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

संबंधित मुद्दे