2013-02-11 29 views
5
class a //my base abstract class 
{ 
public: 
virtual void foo() = 0; 
}; 

class b : public a //my child class with new member object 
{ 
public: 
void foo() 
{} 
int obj; 
}; 

int main() 
{ 
b bee; 
a * ptr = &bee; 
ptr->obj; //ERROR: class a has no member named "obj" 
} 

मेरा प्रश्न है, मैं कैसे "obj" सदस्य का उपयोग कर सकते है जब मैं आधार वर्ग ("एक") के लिए एक सूचक है बच्चे वर्ग की ओर इशारा करते ("ख के लिए सूचक का उपयोग कर के सदस्यों ") वस्तु? मुझे पता है कि कास्टिंग को चाल करना चाहिए लेकिन मैं बेहतर समाधान की तलाश में हूं।तक पहुँचना बच्चे कक्षा एक आधार Abstact वर्ग

+0

कुछ संदर्भ मदद करेंगे। आप ऐसा क्यों करना चाहते हैं? यदि कास्टिंग एक विकल्प नहीं है तो आपको अपने व्युत्पन्न वर्ग में वर्चुअल फ़ंक्शन ओवरराइड करना होगा जो उस सदस्य को संदर्भ या सूचक देता है। हालांकि, यह आम तौर पर encapsulation तोड़ता है। यह हमें वापस लाता है कि आप व्युत्पन्न वर्ग सदस्य को बेस क्लास में पॉइंटर के माध्यम से क्यों एक्सेस करना चाहते हैं? – Void

+0

@ शून्य शायद आप सही हैं, मुझे डिज़ाइन बदलना चाहिए। – user1873947

उत्तर

7

आप dynamic_cast<> ऑपरेटर का उपयोग a पर एक सूचक को b पर कनवर्ट करने के लिए कर सकते हैं। रूपांतरण केवल तभी वस्तु के रन-टाइम प्रकार के ptrb है द्वारा बताया सफल होगा, और एक नल पॉइंटर अन्यथा वापस आ जाएगी, तो आप परिवर्तित करने के बाद परिणाम की जांच करना चाहिए: आप की गारंटी कर सकते हैं कि

b* p = dynamic_cast<b*>(ptr); 
if (p != nullptr) 
{ 
    // It is safe to dereference p 
    p->foo(); 
} 

ptr द्वारा इंगित ऑब्जेक्ट का प्रकार b है, हालांकि, इस मामले में (क्योंकि कोई वर्चुअल विरासत शामिल नहीं है) आप static_cast<> का भी उपयोग कर सकते हैं, जो कम ओवरहेड में होता है क्योंकि यह संकलन-समय पर किया जाता है।

b* p = static_cast<b*>(ptr); 
// You are assuming ptr points to an instance of b. If your assumption is 
// correct, dereferencing p is safe 
p->foo(); 
3

आपको विरासत पदानुक्रम को नीचे डालना होगा। आपका केस उपयुक्त प्रकार के लिए dynamic_cast का उपयोग करने के लिए तैयार है, क्योंकि यदि आप जिस ऑब्जेक्ट को डालने का प्रयास कर रहे हैं, वह वास्तव में अपेक्षित प्रकार का है तो आपको एक प्रकार-सुरक्षित तरीके से जांचने की अनुमति मिलती है।

+0

मैंने गतिशील_कास्ट के बारे में नहीं सोचा था, जो समस्या को हल करना चाहिए क्योंकि यह टाइप-सुरक्षित है। – user1873947

1

जीसीसी और बजना (और दृश्य स्टूडियो में मुझे लगता है कि) आप निम्न वाक्यात्मक चीनी

if (Base* x = dynamic_cast<Base*>(x)) { 
    // do something with \c x now that we know its defined  
} 

का उपयोग करें और में कर सकते हैं सी ++ 11, auto प्रकार निष्कर्ष, यहां तक ​​कि अच्छे

का उपयोग कर
if (auto x = dynamic_cast<Base*>(x)) { 
    // do something with \c x now that we know its defined  
} 

और अंत में अगर हम करने के लिए प्रतिबंधित करना चाहते हैं रीड-ओनली पहुंच

if (const auto x = dynamic_cast<Base*>(x)) { 
    // read something from \c x now that we know its defined  
} 

ध्यान दें कि यह x के दायरे को उस खंड (ओं) के अंदर अच्छी तरह से सीमित करता है जो अक्सर if और else if का उपयोग करके एक दूसरे के बाद कई लगातार गतिशील_कास्ट करते हैं।

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

  • कोई संबंधित समस्या नहीं^_^