2012-01-10 13 views
5
लागू नहीं है

संभव डुप्लिकेट:कॉपी निर्माता

#include <iostream> 

using namespace std; 

class sample 
{ 
    private: 
     int x; 

    public: 
     sample(int a=0) : x(a) 
     { 
      cout << "default ctor invoked\n"; 
     } 

     sample(const sample& obj) 
     { 
      cout << "copy ctor invoked\n"; 
     } 

}; 

int main() 
{ 
    sample s2 = sample(20); //Line1 
    sample s3 = 20; //Line2 

    return 0; 
} 

Line1 में, पहली sample वर्ग के निर्माता शुरू हो जाती है:
Why copy constructor is not called in this case?

नीचे दिए गए नमूना कार्यक्रम पर विचार करें तर्क के साथ explicitly 20. फिर मुझे उम्मीद थी एस 2 शुरू करने के लिए नकल कन्स्ट्रक्टर को बुलाया जाएगा।

लाइन 2 में, पहले sample वर्ग के निर्माता को implicitly पहले तर्क 20 के साथ बुलाया गया है। यहां भी मुझे उम्मीद है कि प्रतिलिपि बनाने के लिए कॉपी कन्स्ट्रक्टर को बुलाया जाएगा।

दोनों मामलों में, कॉपी कन्स्ट्रक्टर का आह्वान नहीं किया जाता है? ये क्यों हो रहा है? मेरा मानना ​​है कि कॉपी कन्स्ट्रक्टर के आविष्कार की मेरी समझ में कुछ गड़बड़ है। क्या कोई मुझे सही कर सकता है जहां मैं गलत हो रहा हूं?

+0

यह अपेक्षित है - मुझे एक अच्छा उदाहरण खोजने की कोशिश करें और –

+0

कॉपी कन्स्ट्रक्टर को कॉल कुछ स्थितियों में elided किया जा सकता है। –

+0

@ आर। मार्टिन्होफर्नैंड्स: हां कुछ स्थितियां। लेकिन एस 2 और एस 3 को कुछ तरीकों से शुरू किया जाना है। प्रतिलिपि ctor कॉल किए बिना यह कैसे किया जाता है? –

उत्तर

8

यह उम्मीद है। इसे copy elision कहा जाता है।

आपकी अपेक्षा सही है, लेकिन उन्होंने सी ++ (प्रदर्शन के लिए) में अपवाद किया है जो प्रतिलिपि को प्रतिबिंबित करते समय संकलक को एक उदाहरण के प्रत्यक्ष प्रारंभ के रूप में आपकी अभिव्यक्ति का इलाज करने की अनुमति देता है।

+0

पहले उदाहरण के लिए हाँ, संकलक प्रतिलिपि बनाने का निर्णय ले सकता है या ऐसा करने के लिए नहीं। लेकिन मुझे लगता है कि दूसरी पंक्ति में, 'नमूना एस 3 = 20;', फिर कंपाइलर * चाहिए * बस 'int' कन्स्ट्रक्टर को कॉल करें। मुझे लगता है कि मैं पूछ रहा हूं "दोनों मामलों में elision * वैकल्पिक * कॉपी है?" –

+1

कोई भी काम करेगा यदि कॉपी कन्स्ट्रक्टर पहुंच योग्य नहीं है (यानी 'निजी') या हटा दिया गया है। तो यह * बिल्कुल * प्रत्यक्ष प्रारंभिक के रूप में नहीं माना जाता है। –

+0

दोनों को कॉपी प्रारंभिकरण की आवश्यकता होती है। दोनों 'नमूना एस के बराबर हैं (नमूना (20)); '। आप प्रतिलिपि ctor निजी बनाने के बाद संकलन करके साबित कर सकते हैं। कॉपी elision की आवश्यकता नहीं है। यह संकलक अनुकूलन के लिए मानक द्वारा * अनुमति * है। चाहे वह elided है या नहीं आपके कंपाइलर पर है। – justin

0

पहली पंक्ति में यह कॉपी कन्स्ट्रक्टर का आह्वान नहीं करता है क्योंकि आप किसी ऑब्जेक्ट की प्रतिलिपि नहीं बनाते हैं। आप एक ऑब्जेक्ट को दूसरे को असाइन कर रहे हैं। सी ++ डिफ़ॉल्ट = ऑपरेटर प्रदान करता है जो उथले प्रतिलिपि करता है। और यह पूरी तरह से लागू किया जाता है। निर्माता को दाएं हाथ की वस्तु के लिए बुलाया जाता है और बाएं हाथ की वस्तु के लिए डिफ़ॉल्ट कन्स्ट्रक्टर का आह्वान किया जाता है। उसके बाद डिफ़ॉल्ट = ऑपरेटर लागू किया जाता है।

लाइन 2 के लिए, यह कन्स्ट्रक्टर का उपयोग करता है जो आपके द्वारा परिभाषित int पैरामीटर लेता है। यह वास्तव में कनवर्टर कन्स्ट्रक्टर है क्योंकि यह एक पूर्णांक लेता है और आपकी कक्षा का ऑब्जेक्ट बनाता है। Thats क्यों C++ कनवर्टर कन्स्ट्रक्टर के रूप में इसका उपयोग करते हैं और जब आप अपनी ऑब्जेक्ट को एक पूर्णांक असाइन करने का प्रयास करते हैं, तो C++ इस कनवर्टर कन्स्ट्रक्टर को अनिवार्य रूप से आमंत्रित करता है।

मुझे उम्मीद है कि यह आपको समझने में मदद करेगा।

+0

सेमल: लाइन 1 पर आपकी व्याख्या सही नहीं है मुझे लगता है। जैसा कि मैंने उन लोगों से समझा है जिन्होंने उत्तर और टिप्पणियां दी हैं, लाइन 1 और लाइन 2 दोनों प्रारंभिक प्रतिलिपि हैं, लेकिन संकलक प्रतिलिपि बनाने वाले को कॉल करने से रोककर इसे प्रत्यक्ष-प्रारंभिक करने के लिए अनुकूलित करता है। –

+1

हाँ आपके पास सही है। जब आप = ऑपरेटर का उपयोग करते हैं तो आम तौर पर यह प्रतिलिपि बनाने वाले का उपयोग करता है लेकिन मुझे पूछे जाने वाले पाठ के अनुसार मुझे एहसास नहीं हुआ। जैसा कि आपने कहा था कि मैंने संकलक अनुकूलन के बारे में नहीं सोचा और सीधे सोचें। आपकी चेतावनी के लिए धन्यवाद –