2012-01-08 16 views
6

मैं अब सीटीओ सीख रहा हूं और कुछ सवाल हैं।सी ++ ऑब्जेक्ट सृजन और कन्स्ट्रक्टर

Foo obj(args); 

Foo obj2; 
obj = Foo(args); 

Foo obj3 = Foo(args); 

पहला भाग: केवल 1 निर्माता कहा जाता है (फू) और obj आरंभ नहीं हो जाता इन लाइनों पर। तो, 1 वस्तु निर्माण।

दूसरा भाग: अस्थायी ऑब्जेक्ट obj2 का निर्माण, इसके लिए डिफ़ॉल्ट ctor को कॉल करना। अगली पंक्तियां हम Foo की एक और प्रतिलिपि बनाते हैं और इसकी प्रतिलिपि operator=() में पास करते हैं। क्या वह सही है? तो, 3 स्थानीय अस्थायी वस्तुओं, 2 कन्स्ट्रक्टर कॉलिंग।

तीसरा भाग: 1 वस्तु Foo बनाने और इसे operator=() में कॉपी है गुजरती हैं। तो, 2 temprorary वस्तुओं और 1 सीटीआर कॉलिंग।

क्या मैं यह अधिकार समझता हूं? और यदि यह सच है, तो संकलक (आखिरी जीसीसी, उदाहरण के लिए) सामान्य मामलों में इन्हें अनुकूलित करेगा?

+0

'ऑपरेटर =() 'आमतौर पर संदर्भ द्वारा अपना तर्क प्राप्त करता है, इसलिए इसे कॉल करने में कोई प्रतियां नहीं होती हैं। – rodrigo

+0

obj3 वास्तव में कॉपी कन्स्ट्रक्टर का उपयोग करके असाइनमेंट ऑपरेटर नहीं बनाया गया है। –

उत्तर

6

मैं तीसरा पहली पर टिप्पणी करेंगे:

Foo obj3=Foo(args); 

यह operator= जो कॉपी-काम कहा जाता है का उपयोग नहीं करता। इसके बजाय यह कॉपी-कन्स्ट्रक्टर (सैद्धांतिक रूप से) का आह्वान करता है। यहां कोई असाइनमेंट नहीं है। तो सैद्धांतिक रूप से, दो वस्तुओं का निर्माण होता है, एक अस्थायी है और अन्य obj3 है। कंपाइलर अस्थायी ऑब्जेक्ट सृजन को पूरी तरह से eliding, कोड अनुकूलित कर सकते हैं।

अब, दूसरा एक:

Foo obj2;   //one object creation 
obj = Foo(args); //a temporary object creation on the RHS 

यहाँ पहली पंक्ति, एक वस्तु बनाता है डिफ़ॉल्ट निर्माता बुला। फिर यह operator= को Foo(args) अभिव्यक्ति से निर्मित अस्थायी ऑब्जेक्ट को गुजरता है। तो दो ऑब्जेक्ट्स केवल operator=const संदर्भ (जो इसे करना चाहिए) द्वारा तर्क लेता है।

और पहले के बारे में, आप सही हैं।

+0

ठीक है, धन्यवाद। लेकिन वैसे भी, पहले मामले में 'Foo' प्रकार के केवल 1 ऑब्जेक्ट्स बनाए गए हैं, तीसरे में: 2 ऑब्जेक्ट्स? – Ockonal

+0

नहीं, चश्मे के अनुसार, भाग 1 और भाग 3 एक ही चीज़ को निर्दिष्ट करने के दो तरीके हैं। कार्यान्वयन में कोई अंतर नहीं है। –

+2

@Mrlister: नहीं। '1' और' 3' के बीच एक सूक्ष्म अंतर है। बस एक टेस्ट कोड लिखें, और कॉपी-कन्स्ट्रक्टर 'प्राइवेट' बनाएं। पहला संकलन करेगा, तीसरा नहीं होगा! – Nawaz

3
  1. हाँ, Foo obj(args) एक फू वस्तु बनाता है और एक बार ctor कहता है।

  2. obj2 को अस्थायी वस्तु नहीं माना जाता है। लेकिन जैसे 1 Foo obj2 एक ऑब्जेक्ट बनाता है और Foo ctor को कॉल करता है। मान लें कि अगली पंक्ति के लिए आपको obj2 = Foo(args) का अर्थ है, यह लाइन एक अस्थायी Foo ऑब्जेक्ट बनाती है और फिर obj2.operator=() पर कॉल करती है। तो इस दूसरे उदाहरण के लिए केवल एक ही अस्थायी वस्तु है, एक गैर-अस्थायी, फू ctors को दो बार कहा जाता है (एक बार अस्थायी के लिए, एक बार अस्थायी के लिए) और ऑपरेटर =() को एक बार बुलाया जाता है।

  3. नहीं, यह लाइन operator=() पर कॉल नहीं करती है। जब आप को = सिंटैक्स का उपयोग करके प्रारंभ करते हैं तो यह लगभग बिल्कुल ठीक है जैसे आपने ब्रांड्स का उपयोग किया था: Foo obj3(Foo(args)); तो यह लाइन एक अस्थायी वस्तु बनाती है, और उसके बाद उस अस्थायी ऑब्जेक्ट का उपयोग करके obj3 को प्रारंभ करने के लिए Foo copy ctor को कॉल करता है।

1

आपकी शब्दावली थोड़ा उलझन में है।

ऑब्जेक्ट्स obj, obj2obj3 को "अस्थायी वस्तुएं" नहीं कहा जाता है। केवल ओबीजे को असाइन करने से पहले लाइन 3 में बनाया गया उदाहरण एक अस्थायी वस्तु है।

इसके अलावा, आप "फू की एक प्रति" नहीं बनाते हैं, तो आप या तो "फू का एक उदाहरण" या "प्रकार की वस्तु का प्रकार" बनाते हैं।

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