2014-07-24 15 views
5

में कहा जाता है पर विचार करें i के बाद से कोडजब वास्तव में नाशक सी ++

int i; 

class A 
{ 
public: 
    ~A() 
    { 
     i=10; 
    } 
}; 

int foo() 
{ 
    i=3; 
    A ob; 
    return i; 
} 

int main() 
{ 
    cout << foo() << endl; 
    return 0; 
} 

निम्नलिखित वैश्विक है, मैंने सोचा था कि इस कार्यक्रम का उत्पादन 10 होना चाहिए। ob, जब यह दायरे से बाहर हो जाता है तो वह विनाशक को कॉल करेगा जिसे i से 10 पर सेट करना चाहिए।

+5

'}' ब्रेस सी ++ में बहुत सारे कोड उत्पन्न करता है :) –

+0

@ हंसपैसेंट कभी भी ऐसी भाषा पर भरोसा न करें जहां "एंड ब्लॉक" कीवर्ड स्वयं ट्यूरिंग पूर्ण हो। ;-) – Sneftel

उत्तर

4

ob रिटर्न निष्पादित होने के बाद दायरे से बाहर हो जाता है। गौर करें कि क्या होगा यदि ob वापसी अभिव्यक्ति के मूल्यांकन में शामिल था और यह वापसी से पहले दायरे से बाहर हो गया होता।

4

ob दायरे के अंत तक दायरे से बाहर नहीं जाता है, यानी } पर return कथन के बाद होता है। वह तब होता है जब विनाशक को बुलाया जाता है, लेकिन तब तक i का मूल्यांकन किया जा चुका है, इसलिए इसका पुराना मान वापस कर दिया गया है।

15

स्थानीय चर दायरे से बाहर निकलते हैं, और उनके विनाशकों को फ़ंक्शन रिटर्न के बाद निष्पादित किया जाता है। जिसका अर्थ है कि ~A() रन तक, वापसी मूल्य पहले से ही है। इसके विपरीत, यदि आप इस किया था ...

int foo() 
{ 
    { 
     i=3; 
     A ob; 
    } 
    return i; 
} 

... ob क्षेत्र से बाहर जाने के लिए और वापसी कथन से पहले मर जाएगा, और परिणाम 10

अतिरिक्त स्कोप अक्सर इस का उपयोग किया जाता होगा एक कार्य के केवल भाग के लिए कुछ विशेष दुष्प्रभाव-पूर्ण स्थिति में जाने के लिए, scoped_lock जैसे आरएआईआई-सक्रिय प्रकारों के साथ।

6
int foo() 
{ 
    i=3; 
    A ob; 
    return i; 
} // <- ~A() is called here 

~A() समारोह foo(), के अंत में कहा जाता है जब ob दायरे से बाहर चला जाता है है। रिटर्न वैल्यू की गणना के बाद यह है (यानी उस समय के मूल्य के साथ i की एक प्रति)।

i10 पर फ़ंक्शन से बाहर होने के लिए सेट करने के लिए, आपको ob को पहले "दायरे से बाहर" जाने के लिए मजबूर करना होगा। सबसे आसान A ob के आसपास एक अतिरिक्त दायरा जोड़ना है।

int foo() 
{ 
    i=3; 
    { 
    A ob; 
    } // <- ~A() is called here and sets i to 10 
    return i; 
} 
3

~A() कहा जाता है जब ob दायरे से बाहर चला जाता है है। विधानसभा सबूत:

<__Z3foov>: 
    push %ebp 
    mov %esp,%ebp 
    push %ebx 
    sub $0x10,%esp 
    movl $0x3,0x407020  /* <-- setting i to 3 */ 
    mov 0x407020,%ebx  /* <-- loading i to %ebx */ 
    lea -0x5(%ebp),%eax 
    mov %eax,%ecx 
    call 403860 <__ZN1AD1Ev> /* <-- calling destructor */ 
    mov %ebx,%eax   /* <-- returnign already calculated i from %ebx */ 
    add $0x10,%esp 
    pop %ebx 
    pop %ebp 
    ret 

<__ZN1AD1Ev>:    /* <-- the destructor */ 
    push %ebp 
    mov %esp,%ebp 
    sub $0x4,%esp 
    mov %ecx,-0x4(%ebp) 
    movl $0xa,0x407020 /* <-- set i to 10 */ 
    leave 
    ret 

आप देख सकते हैं, नाशक के बाद वापसी मान %ebx करने के लिए रखा जाता है कहा जाता है, जब नाशक किया जाता है जो फिर %eax में ले जाया गया है। सी ++ कोड के व्यवहार के बारे में आपके भविष्य के प्रश्नों के लिए, डिस्सेप्लर आपका सबसे अच्छा दोस्त है।

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