2010-03-12 15 views
24
class Base 
{ 
    public: 
    int base_int; 
}; 

class Derived : public Base 
{ 
    public: 
    int derived_int; 
}; 

Base* basepointer = new Derived(); 
basepointer-> //Access derived_int here, is it possible? If so, then how? 
+3

derivedpointer का उपयोग कर आप वास्तव में निजी वंशानुक्रम का उपयोग करने का मतलब यह है व्युत्पन्न वर्ग का उपयोग कर सकते हैं? –

+1

किसी था.मैं परिवर्तन सिर्फ एक चरित्र के लिए एक स्टेटमेंट टर्मिनेटर जोड़ें। –

उत्तर

38

नहीं से प्राप्त वर्ग के सदस्य, आप उपयोग नहीं कर सकते derived_int क्योंकि derived_intDerived का हिस्सा है, जबकि basepointerBase के लिए सूचक है।

आप इसे दूसरी तरह के दौर हालांकि कर सकते हैं:

Derived* derivedpointer = new Derived; 
derivedpointer->base_int; // You can access this just fine 

व्युत्पन्न वर्गों आधार वर्ग, चारों ओर नहीं दूसरी तरह के सदस्यों के वारिस।

Base* basepointer = new Derived; 
static_cast<Derived*>(basepointer)->derived_int; // Can now access, because we have a derived pointer 

ध्यान दें कि आप public पहले करने के लिए अपने विरासत को बदलना होगा:

class Derived : public Base 

हालांकि, अगर आपकी basepointerDerived का एक उदाहरण की ओर इशारा करते था तो आप इसे एक डाली के माध्यम से यहां पहुंच सकता है

+1

वह static_cast के बजाय dynamic_cast उपयोग नहीं करना चाहिए? –

+9

यह निर्भर करता है या नहीं, वह जानता है कि यह एक 'Derived' है या नहीं। यदि आप 100% निश्चित हैं (जैसा कि हम यहां हैं) तो 'static_cast' ठीक है। –

+0

हर किसी static_cast की reinterpret_cast बजाय नहीं क्या मतलब है? मैं बहुत यकीन है कि static_cast संकलन नहीं होगा। – Balk

9

आप यहाँ सुरंग पर नृत्य कर रहे हैं। आधार वर्ग कभी नहीं जानता कि यह वास्तव में व्युत्पन्न का एक उदाहरण है। ऐसा करने के लिए सबसे सुरक्षित तरीका आधार में एक आभासी समारोह शुरू करने की होगी:

class Base 
{ 
protected: 
virtual int &GetInt() 
{ 
    //Die horribly 
} 

public: 
int base_int; 
}; 

class Derived : Base 
{ 
    int &GetInt() 
    { 
    return derived_int; 
    } 
public: 
int derived_int 
}; 

basepointer->GetInt() = 0; 

तो basepointer अंक अन्य है कि एक व्युत्पन्न कुछ के रूप में, अपने कार्यक्रम बुरी तरह मर जाएगा, जो इच्छित परिणाम है।

वैकल्पिक रूप से, आप dynamic_cast (basepointer) का उपयोग कर सकते हैं। लेकिन इसके लिए आपको बेस में कम से कम एक वर्चुअल फ़ंक्शन की आवश्यकता है, और शून्य का सामना करने के लिए तैयार रहें।

static_cast <>, कुछ सुझाव दे, अपने आप को पैर में गोली मार करने के लिए एक यकीन है कि तरीका है। "सी भाषा परिवार की असहाय" डरावनी कहानियों के विशाल कैश में योगदान न दें।

+0

"वैकल्पिक रूप से, आप गतिशील_कास्ट (बेसपोइंटर) का उपयोग कर सकते हैं। लेकिन इसके लिए बेस में कम से कम एक वर्चुअल फ़ंक्शन की आवश्यकता है, और शून्य का सामना करने के लिए तैयार रहें।" -> अच्छा प्वाइंट सेवा। इसे पसंद किया गया :) – mahesh

+3

'static_cast' का उपयोग करके पैर में खुद को शूट करने का कोई तरीका नहीं है। मुझे लगता है कि आप इसे सी के स्पष्ट कास्ट नोटेशन '(टी) एक्स' के साथ भ्रमित कर रहे हैं। दूसरी तरफ 'static_cast' टाइप सुरक्षित है, लेकिन 'dynamic_cast' एक शून्य सूचक लौटाएगा यदि यह परिवर्तित नहीं हो सकता है, जबकि' static_cast' एक कंपाइलर त्रुटि जारी करेगा। – 0x499602D2

4

आप उपयोग CRTP

आप मूल रूप से आधार वर्ग

3

यह व्युत्पन्न वर्ग के प्रकार पता आधार वर्ग की अनुमति से संभव है के लिए टेम्पलेट में व्युत्पन्न वर्ग का उपयोग कर सकते हैं। यह आधार वर्ग को व्युत्पन्न प्रकार का एक टेम्पलेट बनाकर किया जा सकता है। यह सी ++ मुहावरा curiously recurring template pattern कहा जाता है।

व्युत्पन्न वर्ग को जानने का, आधार वर्ग सूचक स्थिर के casted व्युत्पन्न प्रकार के सूचक के लिए हो सकता है।

template<typename DerivedT> 
class Base 
{ 
public: 
    int accessDerivedField() 
    { 
     auto derived = static_cast<DerivedT*>(this); 
     return derived->field; 
    } 
}; 


class Derived : public Base<Derived> 
{ 
public: 
    int field; 
}; 

int main() 
{ 
    auto obj = new Derived; 
    obj->accessDerivedField(); 
} 
0

// आप जानते हैं कि वर्ग व्युत्पन्न का उपयोग करने जा रहे हैं

व्युत्पन्न * derivedpointer = dynamic_cast < व्युत्पन्न *> basepointer;

// तो आप

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