2010-09-26 10 views
16

मैं सी ++ में एक नया प्रोग्रामर हूं। और मैं पहली बार टेम्पलेट का उपयोग कर रहा हूँ।टेम्पलेट विरासत सी ++

मेरे पास एक अमूर्त वर्ग और एक और वर्ग है जो इसे विस्तारित करता है। लेकिन सभी सार वर्ग के संरक्षित सदस्यों अन्य वर्ग द्वारा मान्यता प्राप्त नहीं कर रहे हैं:

class0.h:

template<class T> 
class class0 { 

protected: 
    char p; 
public: 
    char getChar(); 
}; 

**class1.h** 
template<class T> 
class class1:public class0<T> { 
public: 
    void printChar(); 
}; 
template<class T> 
void class1<T>::printChar(){ 
    cout<< p<<endl;//p was not declared in this scope 
} 

धन्यवाद। एक अच्छा सप्ताह है =)

+0

आपके बेस क्लास को या तो सार्वजनिक वर्चुअल विनाशक, या संरक्षित/निजी गैर-आभासी विनाशक की आवश्यकता है। – GManNickG

+0

बीटीडब्ल्यू, इस वर्ग में कौन सा सार है? – Chubsdad

उत्तर

26

ऐसा होने का कारण टेम्पलेट्स के लिए लुकअप नियमों के साथ करना है।

p एक आश्रित अभिव्यक्ति नहीं है क्योंकि यह केवल एक पहचानकर्ता है और कुछ ऐसा नहीं है जो टेम्पलेट पैरामीटर पर निर्भर करता है। इसका अर्थ यह है कि टेम्पलेट पैरामीटर पर निर्भर आधार वर्गों को p नाम को हल करने के लिए खोज नहीं की जाएगी। इस समस्या को हल करने के लिए आपको कुछ ऐसा उपयोग करने की आवश्यकता है जो टेम्पलेट पैरामीटर पर निर्भर करता है। this-> का उपयोग करना यह करेगा।

उदा।

cout << this->p << endl; 
+0

धन्यवाद! मदद मिली =) एक अच्छा दिन है! – yonka

+3

@ योंका: आपको उसका जवाब स्वीकार करना चाहिए। – GManNickG

+0

@GMan: मुझे नहीं पता; litb ने अब एक जवाब पोस्ट किया है। :-) –

2

मुझे वीसी 9 में उस कंपाइलर त्रुटि नहीं मिलती है। हालांकि, कोड के साथ कई समस्याएं हैं: सबसे पहले, इसे टेम्पलेट क्लास होने की आवश्यकता नहीं है क्योंकि यह वर्तमान में लिखा गया है ... लेकिन हो सकता है कि आपने इसे इस प्रश्न के लिए सरल बना दिया हो? दूसरा, बेस क्लास में आभासी विनाशक होना चाहिए।

#include <iostream> 

using namespace std; 

class class0 { 
public: 
    virtual ~class0(){} 

protected: 
    char p; 
public: 
    char getChar(); 
}; 

class class1 : public class0 { 
public: 
    void printChar(); 
}; 

void class1::printChar(){ 
    cout << p << endl;//p was not declared in this scope 
} 

int main() { 
    class1 c; 
    c.printChar(); 
    return 1; 
} 

आप टेम्पलेट के बारे में सीख रहे हैं के बाद से, मैं मिश्रण अवधारणाओं (विरासत & टेम्पलेट्स) सीखने, जबकि नहीं सुझाव है। इस तरह एक सरल उदाहरण के साथ शुरू करो ...

#include <iostream> 
#include <string> 

using namespace std; 

template <typename T> 
T add(const T& a, const T& b) { 
    return a + b; 
} 

int main() { 
    int x = 5; 
    int y = 5; 

    int z = add(x, y); 
    cout << z << endl; 

    string s1("Hello, "); 
    string s2("World!"); 

    string s3 = add(s1, s2); 
    cout << s3 << endl; 

    return 1; 
} 

उपरोक्त कोड में महत्वपूर्ण अवधारणा है कि हम लिखा एक समारोह (उस बात के लिए और कई अन्य प्रकार के) पूर्णांकों और तार जोड़ने के बारे में जानता है कि।

+4

बेस क्लास में वर्चुअल विनाशक क्यों होना चाहिए? टेम्पलेट्स को अक्सर पैरामीट्रिक पॉलिमॉर्फिज्म को लागू करने के लिए उपयोग किया जाता है, और आभासी विलोपन गतिशील बहुरूपता के लिए केवल उपयोगी होता है (और केवल तभी हटाया जाता है जब विलुप्त होने पर पॉलिमॉर्फिक किया जाता है)। –

+1

विजुअल स्टूडियो 2008 कंपाइलर इस मामले में टेम्पलेट लुकअप नियमों को सही ढंग से कार्यान्वित नहीं करने के लिए जाना जाता है। यही कारण है कि आपको त्रुटि दिखाई नहीं दे रही है। –

+0

@ बेन वोगेट, अच्छा बिंदु लेकिन ओपी सिर्फ टेम्पलेट्स से शुरू हो रहा है और मैं अनुमान लगा रहा था कि उन्होंने शायद अभी तक इसे कवर नहीं किया है। लेकिन ऐसा लगता है कि उन्होंने विरासत को कवर किया है और जब तक कि वह विशेष रूप से संकलन-समय बहुलक के लिए नहीं जा रहा है, यह बेस विनाशक वर्चुअल बनाने के लिए सबसे सुरक्षित है। – dgnorton

14

के लिए एक नाम एक आश्रित आधार वर्ग में देखा जा करने के लिए, दो की स्थिति से संतुष्ट

  • यह आवश्यक है कि देखने अयोग्य नहीं है करने की आवश्यकता है
  • यह आवश्यक कि नाम है आश्रित

सी ++ 03 में बताए गए ये नियम rules stated by unrevised C++98 से अलग हैं, जहां दूसरी बुलेट को संतुष्ट करना (नाम बनाना आश्रित) निर्भर आधार वर्गों में घोषित नाम खोजने के लिए पर्याप्त था।

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

this->p 
class1::p 

दोनों नामों p निर्भर कर रहे हैं और पहले संस्करण वर्ग के सदस्य पहुंच देखने उपयोग करता है और दूसरे संस्करण योग्य नाम देखने का उपयोग करता है का उपयोग कर सकते हैं।

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