2013-02-20 49 views
7

में भंडारण आवंटन मैं सी ++ अध्याय 6 प्रारंभिक & सफाई में सोच रहा हूं। लेखक ने कहा कि:सी ++

यह वास्तव में अधिक संभावना है कि संकलक कि गुंजाइश के उद्घाटन ब्रेस पर एक क्षेत्र के लिए सभी भंडारण आवंटन की सी में अभ्यास का पालन करेंगे है। इससे कोई फर्क नहीं पड़ता क्योंकि, प्रोग्रामर के रूप में, आप तब तक स्टोरेज तक पहुंच नहीं सकते जब तक इसे परिभाषित नहीं किया जाता है। हालांकि स्टोरेज ब्लॉक की शुरुआत में आवंटित है, कन्स्ट्रक्टर कॉल तब तक होता है जब तक ऑब्जेक्ट परिभाषित नहीं किया जाता है क्योंकि पहचानकर्ता तब तक उपलब्ध नहीं है। कंपाइलर भी पर जांच करता है सुनिश्चित करें कि आप ऑब्जेक्ट परिभाषा नहीं डालते हैं जहां अनुक्रम बिंदु केवल सशर्त रूप से इसके माध्यम से गुजरता है, जैसे स्विच कथन या कहीं भी एक गोटो इसे पीछे कूद सकता है।

और फिर लेखक निम्नलिखित के रूप में एक उदाहरण देता है:

class X { 
public: 
    X(); 
}; 

X::X() {} 

void f(int i) { 
    if(i < 10) { 
    //! goto jump1; // Error: goto bypasses init 
    } 
    X x1; // Constructor called here 
jump1: 
    switch(i) { 
    case 1 : 
     X x2; // Constructor called here 
     break; 
    // case 2 : // Error: case bypasses init 
     X x3; // Constructor called here 
     break; 
    } 
} 

int main() { 
    f(9); 
    f(11); 
}///:~ 

क्यों उपरोक्त कोड ठीक है मुझे समझ नहीं आता? मेरी समझ के अनुसार, x2 को i1 नहीं है, तो प्रारंभिकता को बाधित किया जा सकता है।

अनुपूरक: "। It'a वास्तव में अधिक संभावना है कि संकलक कि गुंजाइश के उद्घाटन ब्रेस पर एक क्षेत्र के लिए सभी भंडारण आवंटन की सी में अभ्यास का पालन करेंगे"

यह वाक्य मुझे भी भ्रमित कर दिया।

लेखक के विवरण के अनुसार, switch के उद्घाटन ब्रेस पर, कंपाइलर ने x2 और के लिए पहले ही स्थान आवंटित कर दिया है। यदि ऐसा है, तो x2 के लिए अनियमित होने का अवसर है (केस 1 संतुष्ट नहीं है)।

उत्तर

2

सी ++ ऑब्जेक्ट प्रारंभिकरण और विनाश अर्थशास्त्र पूरी तरह से कूद-सुरक्षित (अपवाद, गोटो, स्विच और लूप संरचना शामिल हैं)।

(केवल उल्लेखनीय अपवाद सी मानक पुस्तकालय (setjmp/longjmp) से प्राप्त होती है)

6,6 कूद बयान

बाहर निकलने पर एक गुंजाइश (हालांकि पूरा किया) से, के साथ वस्तुओं स्वचालित भंडारण अवधि (3.7.3) जो उस क्षेत्र में बनाई गई हैं, उनके निर्माण के विपरीत क्रम में नष्ट हो जाती हैं। [नोट: अस्थायी के लिए, 12.2 देखें। -जेंड नोट] स्वचालित रूप से एक स्टोरेज अवधि के साथ एक प्रारंभिक चर के पीछे एक लूप से बाहर स्थानांतरण, या स्वचालित भंडारण अवधि के साथ ऑब्जेक्ट्स का विनाश शामिल है जो बिंदु से स्थानांतरित बिंदु पर दायरे में हैं, लेकिन बिंदु पर नहीं पर स्थानांतरित कर दिया गया। (ब्लॉक में स्थानान्तरण के लिए 6.7 देखें)। [नोट: हालांकि, प्रोग्राम को समाप्त किया जा सकता है (उदाहरण के लिए std :: exit() या std :: abort() (18.5) को कॉल करके) स्वचालित संग्रहण अवधि के साथ कक्षा वस्तुओं को नष्ट किए बिना।अंत टिप्पणी]

+0

वह नियम सी ++ 03 में था, और शायद सी ++ 98। और यह सी कोड तोड़ नहीं देता है क्योंकि सभी सी ++ मानक अपवाद की अनुमति देते हैं जब initia lized ऑब्जेक्ट में एक सी-संगत प्रकार है। – aschepler

+0

मुझे यकीन नहीं है कि 'ब्रेकिंग सी कोड' के बारे में आपकी टिप्पणी क्या है? हां, इंट्रिनिक्स (पीओडी, मुझे अभी यकीन नहीं है) एक अलग जानवर हैं। पूरी भाषा में। और, हां, जैसा कि मैंने स्पष्ट रूप से दिखाया है, सी ++ 11 – sehe

+0

सी 1 से पहले प्रारंभिक उपकरणों के कूदने के नियम अधिक सी थे, सी और सी ++ के बीच मतभेदों के बारे में है, सी ++ 03 और सी ++ 11 के बीच मतभेदों के बारे में नहीं। सी ++ 11 सी .1.5 कोई बदलाव नहीं है; यह सी ++ 03 सी .1.4 के समान है। आप 6.7 एमपी में परिवर्तन के बारे में बात कर रहे हैं, जो हां, कुछ सी ++ 03 कोड तोड़ता है। – aschepler

5

मेरी समझ के अनुसार, x2 प्रारंभ नजरअंदाज किया जा सकता है अगर मैं 1.

नहीं है नहीं है, या तो case 1 निष्पादित किया जाता है, और x2 परिभाषित किया गया है और फिर से नष्ट किया switch ब्लॉक का अंत, या कोई मामला निष्पादित नहीं किया गया है और पूरे switch ब्लॉक कुछ भी नहीं करता है, इसलिए x2 दायरे में नहीं है, इसलिए इसे प्रारंभ नहीं किया गया है लेकिन इसे या तो संदर्भित नहीं किया जा सकता है। तो या तो यह अस्तित्व में है और उपयोग करने के लिए सुरक्षित है, या यह अस्तित्व में नहीं है।

+0

धन्यवाद वाकई। एक और सवाल, अगर मैं केस 2 को अपूर्ण करता हूं, तो एक त्रुटि होगी। क्यूं कर? – Fihop

+1

क्योंकि तब प्रोग्राम का नियंत्रण प्रवाह 'केस 2' पर जा सकता है और' x2' की शुरुआत को बाईपास कर सकता है, जिसे सी ++ में अनुमति नहीं है, क्योंकि पुस्तक कहती है _ "कंपाइलर यह सुनिश्चित करने के लिए भी जांच करता है कि आप नहीं डालते ऑब्जेक्ट परिभाषा जहां अनुक्रम बिंदु केवल सशर्त रूप से इसके माध्यम से गुजरती है, जैसे कि स्विच स्टेटमेंट या कहीं कहीं गोटो इसे पीछे कूद सकता है। "_ –

+0

हाय जानथन, मैंने सवाल संपादित किया है और एक और सवाल पूछा है। क्या आप मुझे एक बार फिर से एक पक्ष कर सकते हैं। – Fihop

0

इसके साथ समस्या यह है कि जब आप अपने दायरे से बाहर निकलते हैं तो स्थानीय प्रारंभिक चर नष्ट हो जाता है। सी ++ स्विच सोचता है, अगर, जबकि, चर बनाने के संबंध में अपने सभी दायरे हैं।

+0

प्रारंभ नहीं किया गया है, मैंने अपना प्रश्न संपादित कर लिया है। क्या आप इसे देखने में मेरी मदद कर सकते हैं? – Fihop

+0

ठीक है, अब आपने इसे खुद भी कहा है!मैं समझ नहीं पा रहा हूं कि आप क्या समझते हैं, यह इसे अपने स्वयं के दायरे के रूप में देखता है - जब आप स्थानीय चर को प्रारंभ (और आवंटित नहीं करते) - यह उस दायरे के अंत में नष्ट हो जाएगा। – Infested

0

नहीं, x2i1 है, भले ही x2 को बाईपास नहीं किया जा सकता है। goto के साथ समस्या यह होगी कि यदि इसे लिया गया था, तो x1 के लिए निर्माता को कॉल नहीं किया जाएगा (याद रखें, निर्माता को X x1; कथन पर "बुलाया जाता है" - क्योंकि कन्स्ट्रक्टर को कॉल से ऊपर कूदने का लक्ष्य है और आप एक बिंदु है जहां x1 दायरे में अभी भी था पर होगा।

लेकिन आप लाइन X x2; अतीत कूद नहीं कर सकते हैं और एक बिंदु में समाप्त जहां x2अभी भी दायरे में है, इसलिए कि ठीक है।

+0

हाय निक। मैंने सवाल संपादित कर लिया है। क्या आप इसे देखने में मेरी मदद कर सकते हैं? – Fihop