2012-06-20 9 views
5

मैं अपनी विरासत पेड़ में वर्गों में से एक के एक निर्माता के भीतर, एक वस्तु के सबसे व्युत्पन्न वर्ग को खोजने के लिए कोशिश कर रहा हूँ। मैंने अब इस पर कई घंटे बिताए हैं और मैं इस बात के लिए हानि में हूं कि मैं इसे और कैसे कर सकता हूं या इसका अर्थ क्यों नहीं है। ऐसा लगता है कि यह सही समझ में आता है, फिर भी यह काम करने से इंकार कर देता है। मुझे आरटीटीआई के बारे में कई पेज मिल गए हैं और मूल रूप से उनके साथ कहीं भी नहीं मिला है। मैं अपने टेस्ट केस और उसके आउटपुट के बाद समझाऊंगा।क्या यह "पॉइंटर आरटीटीआई-सक्षम है?

स्रोत:

#include <iostream> 
#include <typeinfo> 
#include <string> 

class A 
{ 
public: 
    A(std::string foo); 

    virtual void bar(A* a) = 0; 
}; 

class B : public A 
{ 
public: 
    B(); 

    virtual void bar(A* a); 
}; 

A::A(std::string foo) 
{ 
    std::cout << "type as passed to A constructor: " << foo << " (" << this << ")" << std::endl; 
    std::cout << "type as determined in A constructor: " << typeid(*this).name() << " (" << this << ")" << std::endl; 
} 

B::B() : A(typeid(*this).name()) 
{ 
    A* a = (A*)this; 
    std::cout << "type as determined in B constructor: " << typeid(*a).name() << " (" << this << ")" << std::endl; 
    this->bar(this); 
} 

void B::bar(A* a) 
{ 
    std::cout << "type as determined in bar: " << typeid(*a).name() << " (" << a << ")" << std::endl; 
} 

int main() 
{ 
    B b; 
    b.bar(&b); 

    return 0; 
} 

(++ जी पर) उत्पादन:

type as passed to A constructor: 1B (0x7fff5fbff910) 
type as determined in A constructor: 1A (0x7fff5fbff910) 
type as determined in B constructor: 1B (0x7fff5fbff910) 
type as determined in bar: 1B (0x7fff5fbff910) 
type as determined in bar: 1B (0x7fff5fbff910) 

मैं कहना है बजाय "1 ए" के "1 बी" उत्पादन की दूसरी पंक्ति पाने के लिए कोशिश कर रहा हूँ । आरटीटीआई किसी कारण से "इस" से छीन लिया गया है, मैं अभी तक कल्पना नहीं कर सकता? यह वर्चुअल फ़ंक्शंस के विचार को कैसे तोड़ता है? (मैं आभासी कार्यों के साथ यह लागू किया जब तक मुझे पता चला मैं RTTI, जो मैं पहले की ज्ञात नहीं था का हिस्सा reimplementing किया गया था।) उत्पादन पता चलता है, मैं यह काम कर सकते हैं अगर मैं का उपयोग कर से बचने "इस," लेकिन जरूरत ऐसा करने के लिए डिजाइन द्वारा टूटने की तरह लग रहा है।

+2

आप इस प्रकार का पता लगाने की कोशिश क्यों कर रहे हैं? यह असहज है। यह किसी और चीज के प्रयास (दोषपूर्ण) समाधान की तरह लगता है, यह और कुछ क्या है? –

+0

अल्फ, मेरे पास std :: प्रकार के मानचित्र हैं (std :: स्ट्रिंग्स, इस मामले में) ऑब्जेक्ट्स में, प्रत्येक प्रकार के मानचित्र के भीतर एक अद्वितीय ऑब्जेक्ट होता है। किसी निश्चित वर्ग के प्रत्येक उदाहरण का अपना नक्शा होता है, ताकि इन ऑब्जेक्ट्स में नई ऑब्जेक्ट्स को आसानी से जोड़ा जा सके और बाद में टाइप द्वारा पुनर्प्राप्त किया जा सके। (मैं आरटीटीआई के बारे में जानता था, इससे पहले कि मैं उसी कारण के बराबर विफलता के साथ कॉन्स्टेंट और वर्चुअल तरीकों का एक वेब कर रहा था।) – Grault

उत्तर

4

आप ऐसा नहीं कर सकते कि क्योंकि आप शामिल गतिशीलता गलत।

नियम है:

this निर्माता में/वर्ग जिसका निर्माता/नाशक यह है करने के लिए किसी भी वर्ग अंक की नाशक।

इसके अलावा, इस कारण के रूप में आप सामान्य रूप से जब गतिशील प्रेषण का उपयोग कर काम करने के लिए एक virtual समारोह उम्मीद करेंगे virtual कार्यों निर्माता में कहा जाता है व्यवहार नहीं करते है।

आप प्रकार, के बाद निर्माता किया गया है called.You निर्माता और नाशक छोड़कर सदस्य कार्यों में से किसी में ऐसा कर सकते हैं पता लगा लेगा।

+0

ठीक है, लेकिन यह बेहतर क्यों माना जाता है? यह मेरे लिए सबसे अच्छा लगता है, मेरे लिए। क्या यह कुछ अन्य ओओ सुविधा तोड़ देगा? – Grault

0

अपने विरासत संबंधों पर विचार करें, आपको पहले से ही पता होना चाहिए कि A का निर्माता पहले निष्पादित करेगा और फिर B में से एक होगा। A के कन्स्ट्रक्टर के भीतर, ऑब्जेक्ट अभी तक B नहीं है क्योंकि इसका निर्माण नहीं किया गया है। इसलिए, एक कन्स्ट्रक्टर के भीतर एक वस्तु का गतिशील प्रकार हमेशा वर्ग का प्रकार होता है और कभी भी व्युत्पन्न वर्ग का प्रकार नहीं होता है। विनाशकों में भी यही होता है।

संक्षेप में, आप क्या करना चाहते हैं निर्माण समय पर नहीं किया जा सकता है।

+0

"ए का कन्स्ट्रक्टर पहले निष्पादित करेगा और फिर बी में से एक होगा।" मैंने तब तक सोचा जब तक कि मैं एक बी के रूप में "यह" को एक कन्स्ट्रक्टर में पास करने में सक्षम नहीं था (जिसे परीक्षण मामले में स्पष्ट रूप से प्रदर्शित किया जाता है)। अब मैं सबसे अधिक व्युत्पन्न कन्स्ट्रक्टर के रूप में प्रवाह को समझता हूं, और प्रत्येक कन्स्ट्रक्टर कुछ और करने से पहले अपने माता-पिता को बुलाता है। इस प्रकार शरीर आपके द्वारा जड़ से नीचे चला जाता है। – Grault

3

आप अपेक्षित व्यवहार देख रहे हैं। एक कन्स्ट्रक्टर के शरीर में निर्माण के तहत वस्तु का प्रकार उस वर्ग के प्रकार जैसा होता है जिसका कन्स्ट्रक्टर निष्पादित किया जा रहा है और अधिकांश व्युत्पन्न वर्ग का निर्माण नहीं किया जा रहा है।

विसंगति जब एक सदस्य प्रारंभकर्ता अभिव्यक्ति में इस्तेमाल अभिव्यक्ति typeid(*this) में वास्तव में है। यह सी ++ 03 में अपरिभाषित व्यवहार हुआ करता था, लेकिन यह सी ++ 11 में बदल दिया गया है, ताकि आप निर्माता की क्लास के प्रकार के बजाय वास्तविक वस्तु जो अभी तक का निर्माण किया जा रहा है के प्रकार के हो रही है।

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