2009-01-14 8 views
27

क्या मैं कक्षा के कन्स्ट्रक्टर के भीतर से "यह" एक सूचक के रूप में एक फ़ंक्शन में पास कर सकता हूं, और कन्स्ट्रक्टर रिटर्न से पहले ऑब्जेक्ट के सदस्यों को इंगित करने के लिए इसका उपयोग कर सकता हूं?एक कन्स्ट्रक्टर के भीतर से एक समारोह में "यह" पास कर रहा है?

क्या यह सुरक्षित है, जब तक कि एक्सेस किए गए सदस्यों को फ़ंक्शन कॉल से पहले ठीक से प्रारंभ किया जाता है?

एक उदाहरण के रूप:

#include <iostream> 

class Stuff 
{ 
public: 
    static void print_number(void *param) 
    { 
     std::cout << reinterpret_cast<Stuff*>(param)->number; 
    } 

    int number; 

    Stuff(int number_) 
     : number(number_) 
    { 
     print_number(this); 
    } 
}; 

void main() { 
    Stuff stuff(12345); 
}

मैंने सोचा था कि यह काम नहीं होगा, लेकिन यह लगता है। क्या यह मानक व्यवहार है, या सिर्फ अपरिभाषित व्यवहार मेरे रास्ते जा रहा है?

उत्तर

30

जब आप सी ++ में किसी ऑब्जेक्ट को तुरंत चालू करते हैं, तो कन्स्ट्रक्टर में कोड अंतिम चीज़ निष्पादित होती है। सुपरक्लस प्रारंभिकरण, सुपरक्लास कन्स्ट्रक्टर निष्पादन, और स्मृति आवंटन सहित अन्य सभी प्रारंभिकरण पहले से ही होते हैं। ऑब्जेक्ट का निर्माण होने के बाद कन्स्ट्रक्टर में कोड वास्तव में अतिरिक्त प्रारंभ करने के लिए है। इसलिए यह एक वर्ग के निर्माता में "यह" पॉइंटर का उपयोग करने के लिए पूरी तरह से मान्य है और मान लीजिए कि यह पूरी तरह से निर्मित वस्तु को इंगित करता है।

बेशक, आपको अभी भी प्रारंभिक सदस्य चर से सावधान रहना होगा, अगर आपने उन्हें पहले से ही अपने कन्स्ट्रक्टर कोड में प्रारंभ नहीं किया है।

+4

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

4

आप इस here (सी ++ एफएक्यू) के लिए एक अच्छा जवाब पा सकते हैं।

सभी विरासत सदस्यों और कॉलिंग क्लास के सदस्यों को कन्स्ट्रक्टर के कोड निष्पादन की शुरुआत में निर्माण करने की गारंटी है और इसलिए इसे सुरक्षित रूप से संदर्भित किया जा सकता है।

मुख्य गोचा यह है कि आपको वर्चुअल फ़ंक्शन को this पर कॉल नहीं करना चाहिए। ज्यादातर बार मैंने यह कोशिश की है कि यह बेस क्लास के फ़ंक्शन को कॉल करने के लिए समाप्त होता है, लेकिन मेरा मानना ​​है कि मानक कहता है कि परिणाम अपरिभाषित है।

+0

लिंक प्रकट होता है o टूटा हुआ है ... –

+0

यह शुद्ध वर्चुअल फ़ंक्शंस के लिए अपरिभाषित है (जिसमें अभी तक कोई परिभाषा नहीं है)। –

-2

एंडी, मुझे लगता है कि आप मानक के अनिर्धारित हिस्से के बारे में गलत हैं।

जब आप निर्माता में हैं, "इस" एक वस्तु जिसका प्रकार वस्तु बना रहे हैं, जिसका मतलब है कि आभासी कार्यों आंशिक रूप से आधार वर्ग में लागू हो जाएगा की आधार वर्ग है के लिए सूचक है बुलाया और वर्चुअल टेबल में पॉइंटर्स का पालन नहीं किया जाएगा।

C++ Faq Lite में अधिक जानकारी ...

+0

गलत: जब आप व्युत्पन्न :: व्युत्पन्न दर्ज करते हैं, यह-> पहले ही एक व्युत्पन्न वस्तु को इंगित करता है। यह उदा। से अलग है जावा, यह कहां है। MostDerived ऑब्जेक्ट को इंगित कर सकते हैं। न तो भाषा में यह-> व्युत्पन्न के निर्माता में "ए" बेस क्लास को इंगित करेगा।इसके अलावा, एमआई के साथ, कौन सा आधार इस बिंदु पर होगा? – MSalters

0

प्रस्तुत कोड पर अतिरिक्त नोट के रूप में, मैं बजाय templatize void* होगा:

class Stuff 
{ 
public: 
    template <typename T> 
    static void print_number(const T& t) 
    { 
     std::cout << t.number; 
    } 

    int number; 

    Stuff(int number_) 
    : number(number_) 
    { 
     print_number(*this); 
    } 
}; 

तो फिर तुम एक संकलन त्रुटि अगर मिल चाहते हैं t के प्रकार में number सदस्य नहीं है।

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