2015-05-20 14 views
10

मान लीजिए कि मैं अपने ऑब्जेक्ट के बाहरी फ़ंक्शन को बॉडी कन्स्ट्रक्टर के अंदर कुछ चेक करने के लिए कॉल करना चाहता हूं। चूंकि किसी ऑब्जेक्ट का जीवनकाल तब शुरू होता है जब कन्स्ट्रक्टर का शरीर इसके निष्पादन को समाप्त करता है, क्या यह एक असुरक्षित डिज़ाइन है?सी ++: ऑब्जेक्ट और बाहरी फ़ंक्शंस का जीवनकाल

struct A; 

void check(A const&) { /* */ } 

struct A 
{ 
    A() { check(*this); } 
}; 

मेरा मतलब है, मैं फोन कर रहा हूँ और एक नहीं अभी तक जीवित वस्तु के साथ बाहरी कार्य करते हैं। क्या यह अनिर्धारित व्यवहार है?

संबंधित प्रश्न: यदि मैं उस कार्य फ़ंक्शन को सदस्य फ़ंक्शन (स्थैतिक या नहीं) के रूप में डालता हूं, तो मानक के बिना गैर-जीवित वस्तुओं का उपयोग करने के बारे में मानक कहता है लेकिन कक्षा के अंदर?

क्या कक्षा और उसके उपयोगकर्ताओं (एक कक्षा में बनाम कक्षा के जीवनकाल के प्रकार) के दृष्टिकोण के बीच जीवन भर की अवधारणा में कोई अंतर है?

+2

[सी ++ एफएक्यू] (https://isocpp.org/wiki/faq/ctors#using-this-in-ctors) के बारे में जानकारी है। –

+0

यह तब तक ठीक होना चाहिए जब तक कि फ़ंक्शन सदस्य वर्चुअल न हो और प्रारंभिक सूची में नहीं है – KABoissonneault

+1

एक कॉन्स और एक संदर्भ है और न तो कार्यों की शुरुआत में शुरू किया गया है और न ही कार्यों के अंत में नष्ट हो गया है। कन्स्ट्रक्टर के अंदर वस्तु पूरी तरह से बनाई गई है। मुझे इस कोड में कोई समस्या नहीं दिखाई दे रही है – Brahim

उत्तर

8

जब check() कहा जाता है A के जीवनकाल शुरू कर दिया है नहीं होगा, क्योंकि [base.life] से: प्रकार T का एक उद्देश्य के जीवनकाल शुरू होता है

जब:

  • के साथ भंडारण T टाइप करने के लिए उचित संरेखण और आकार प्राप्त किया गया है, और
  • यदि ऑब्जेक्ट में गैर-प्रारंभिक प्रारंभिकता है, तो इसकी प्रारंभिकता पूर्ण हो गई है।

A गैर असार प्रारंभ है। इसका प्रारंभ कर पूरा करते है, से [class.base.init]/13:

एक गैर सौंपने के निर्माता में, निम्न क्रम में प्रारंभ आय:

  • ...
  • - अंत में, कंपाउंड-स्टेटमेंट के कंपाउंड-स्टेटमेंट निष्पादित किया गया है।

हालांकि, A के बावजूद अपने जीवनकाल अभी तक शुरू नहीं होने, मानक अतिरिक्त [class.base.init]/16 में, प्रदान करता है:

सदस्य कार्य (आभासी सदस्य कार्यों सहित, 10.3) निर्माण के तहत किसी वस्तु के लिए बुलाया जा सकता है ... हालांकि, यदि इन परिचालनों को सीटीओआर-प्रारंभकर्ता (या या अप्रत्यक्ष रूप से सीटीओआर-प्रारंभकर्ता से अप्रत्यक्ष रूप से) मेम- initi आधार वर्गों के लिए को पूरा कर लिया गया है, ऑपरेशन का परिणाम अपरिभाषित है।

void check(const A&) { .. } 
struct A { 
    A() { check(*this); } 
}; 

और::

के साथ जीवन के मुद्दों के संबंध

, वहाँ के बीच कोई अंतर नहीं है

struct A { 
    void check() const { .. } 
    A() { check(); } 
}; 

बाद स्पष्ट रूप से के लिए अनुमति दी है (यह एक ctor-प्रारंभकर्ता में नहीं है के रूप में), इसलिए मुझे जीवनकाल के आधार पर पूर्व को बाहर करने का कोई कारण नहीं दिखता है।

+0

... सिवाय इसके कि यदि वर्चुअल सदस्यों के साथ एक बेस क्लास है जिसे 'चेक()' कहा जाता है - तो परिणाम आपको आश्चर्यचकित कर सकते हैं। –

+0

@RichardHodges हालांकि यह अनिर्धारित व्यवहार नहीं है। – Barry

+0

@ बैरी क्या आप निश्चित हैं कि प्रारंभिकरण समाप्त होता है? http://stackoverflow.com/a/20409911/1794803 –

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