2010-11-10 9 views
6

मेरी कोड:कन्स्ट्रक्टर के अंदर 'इस' के संदर्भ में 'दे रहा है' ठीक है?

Scene::Scene(const std::string &scene_file) : ambient_light(0, 0, 0), background(0, 0, 0){ 
    scene_parser parser(*this); 
    parser.parse(scene_file); 
} 

scene_parser दृश्य के एक दोस्त है, और पार्स विधि में यह (आर/डब्ल्यू) दृश्य के सदस्यों तक पहुँचता है। क्या यह किसी भी समस्या का कारण बन रहा है?

+0

यह कहीं भी ध्यान दिया जाना चाहिए कि यह तब तक ठीक है जब आप 'इस' सूचक को निर्माता निकाय के भीतर से बाहर करते हैं, न कि प्रारंभिक सूची। –

+0

यह भी जांचें कि सी ++ faq-lite क्या कहना है: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.7 – stefaanv

उत्तर

4

आपके विशेष उदाहरण में, कोई समस्या नहीं उठानी चाहिए।

आम तौर पर this संदर्भ देने में समस्या यह है कि दो वस्तुओं के जीवनकाल बिल्कुल संरेखित नहीं होते हैं और अन्य वस्तु पहले से ही नष्ट हो जाने के बाद संदर्भित वस्तु तक पहुंचने का प्रयास कर सकती है।

आपके उदाहरण में, scene_parser ऑब्जेक्ट स्टैक पर है, इसलिए यह Scene कन्स्ट्रक्टर के अंत में जीवनकाल समाप्त होता है। आपके द्वारा प्रदान किए गए this संदर्भ के माध्यम से एक गैर-मौजूद वस्तु तक पहुंचने का कोई भी संभावित तरीका नहीं है, इसलिए कोई समस्या उत्पन्न नहीं हो सकती है।

+3

नहीं, लेकिन अगर 'पार्सर' वर्चुअल 'फ़ंक्शंस को आमंत्रित करता है, तो आपको वांछित प्रभाव नहीं मिलेगा। यद्यपि वह * कानूनी है, लेकिन आप एक बग पर विचार कर सकते हैं (और संभवतः)। –

+0

यह किसी भी पॉइंटर्स को देने के साथ संभावित गॉचा है, कन्स्ट्रक्टर या 'यह' पॉइंटर के लिए विशिष्ट नहीं है। कन्स्ट्रक्टर से 'यह' देने के साथ असली गोचा यह है कि कन्स्ट्रक्टर को इनवेरिएंट स्थापित करने से पहले वर्ग सदस्य कार्यों को बुलाया जा सकता है। –

+1

मैं दृश्य को उपclassing पर इरादा नहीं है, तो ऐसा लगता है कि सब ठीक है। – Bwmat

8

हां, this का संदर्भ देना ठीक है। हालांकि, आप आमतौर पर ऐसा करना चाहते हैं जब अन्य ऑब्जेक्ट बाद में पॉइंटर का उपयोग करेगा। आपका उपयोग केस ऐसा लगता है कि यह Scene का उपयोग करेगा, कन्स्ट्रक्टर पूर्ण होने से पहले, जो एक बहुत फिसलन ढलान है।

अभी, आप parse पर कॉल करने के बाद किसी भी आविष्कार स्थापित नहीं कर रहे हैं, इसलिए यह ठीक होना चाहिए, लेकिन यह भी नाजुक और ब्रेकेज पेश करने के लिए भविष्य में बदलावों के लिए आसान है।

+0

अच्छा उत्तर। मुझे लगता है कि आपको कुछ उत्तरों को अन्य उत्तरों में टिप्पणियों में शामिल करना चाहिए, क्योंकि ऐसा लगता है कि कुछ सूक्ष्मताएं हैं जिन्हें संबोधित किया जाना चाहिए। –

+2

@ वुडोकोकल: वर्चुअल फ़ंक्शंस से संबंधित चेतावनियों को वास्तव में 'इस' सूचक को किसी अन्य ऑब्जेक्ट को सौंपने की आवश्यकता नहीं होती है। आप कक्षा के अपने कार्यों को कन्स्ट्रक्टर के अंदर से कॉल करने में परेशानी में पड़ सकते हैं। इसके अलावा, ओपी ने पहले ही संकेत दिया है कि 'दृश्य' एक टर्मिनल वर्ग है, इसलिए वस्तु का गतिशील प्रकार कोई समस्या नहीं होगी। –

+0

आह, स्पष्टीकरण के लिए धन्यवाद - मैं उसमें बहुत कुछ पढ़ रहा था। –

1

यह निर्भर करता है।

कन्स्ट्रक्टर बॉडी के अंदर (यानी प्रारंभकर्ता सूची निष्पादित हो जाने के बाद), ऑब्जेक्ट को वर्तमान प्रकार तक "पूरी तरह से निर्मित" माना जाता है। इसलिए, आप संदर्भ *this कर सकते हैं, लेकिन virtual फ़ंक्शन कॉल व्युत्पन्न कक्षाओं में ओवरराइड फ़ंक्शंस का उपयोग नहीं करेंगे।

+2

मुझे लगता है कि आपको आभासी कार्यों के लिए कॉल पर पिछड़ा हुआ है, लेकिन यह जानना एक महत्वपूर्ण बात है। –

+0

@ बेन: आप सही हैं, मैंने "व्युत्पन्न" के बजाय "आधार" टाइप किया है। –

0

आपके सभी सबबजेक्ट्स (सदस्य और आधार) का निर्माण कन्स्ट्रक्टर के शरीर में पहले बयान द्वारा किया जाता है। यदि आपकी वस्तु "वैध स्थिति" में है (जो आपकी कक्षा की परिभाषा का हिस्सा है, जिसे कभी-कभी "क्लास इनवेरिएंट" कहा जाता है), तो आप इसे पूरी तरह से निर्मित ऑब्जेक्ट के रूप में देख सकते हैं और इसके साथ कुछ भी कर सकते हैं। हालांकि, आभासी लुकअप अपेक्षाकृत अपेक्षाकृत अलग तरीके से काम करता है या आवश्यकता है: यदि यह एक बेस क्लास है (और इस प्रकार यह ऑब्जेक्ट किसी और चीज का सबब्जेक्ट है), अंतिम प्रकार अभी तक "असाइन नहीं किया गया" है। उदाहरण के लिए, यह शुद्ध-वर्चुअल विधियों को कॉल करने और रनटाइम त्रुटि प्राप्त करने का एक तरीका है (यदि उन विधियों में परिभाषाएं नहीं हैं, वैसे भी)।

एक और दिलचस्प स्थिति का उपयोग कन्स्ट्रक्टर प्रारंभकर्ता में कर रही है; इसमें कुछ चेतावनी हैं, लेकिन यह कन्स्ट्रक्टर बॉडी से पहले भी है।

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

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