2009-04-14 21 views
10

क्या मैं केवल प्रतिलिपि संदर्भ के बजाय एक सूचक में गुजरकर एक प्रतिलिपि लिख सकता हूं? (यह अगर मुझे यकीन है कि मैं किसी भी मूल्यों को बदलने के लिए हालांकि नहीं जा रहा हूँ कर ठीक होगा?)रचनाकारों की प्रतिलिपि बनाएँ - सी ++

तो जैसा

:

SampleClass::SampleClass(SampleClass* p) 
{ 
//do the necessary copy functionality 
} 

के बजाय:

SampleClass::SampleClass(const SampleClass& copyObj) 
{ 
//do the necessary copy 
} 

अग्रिम धन्यवाद।


सभी को धन्यवाद। इसलिए, अगर मैं एक कन्स्ट्रक्टर लिखता हूं जो एक पॉइंटर लेता है (और सोचा कि यह मेरी प्रतिलिपि निर्माता है), तो संकलक अभी भी डिफॉल्ट कॉपी कन्स्ट्रक्टर के साथ आपूर्ति करेगा, जिस स्थिति में मेरा कन्स्ट्रक्टर (जिसे मैंने सोचा था कि मेरी प्रतिलिपि निर्माता थी) को नहीं कहा जाएगा और डिफ़ॉल्ट प्रतिलिपि कन्स्ट्रक्टर कहा जाएगा। समझ गया।

उत्तर

1

सं कॉपी कंस्ट्रक्टर्स, एक संदर्भ रखना चाहिए सूचक नहीं है, अगर यह गुजर-दर-मूल्य के लिए उपयोगी होने के लिए है आदि

4

आप एक निर्माता है कि एक तर्क के रूप में एक सूचक लेता लिख ​​सकते हैं।
लेकिन कॉपी कन्स्ट्रक्टर वह नाम है जिसे हम एक विशिष्ट कन्स्ट्रक्टर देते हैं।
एक कन्स्ट्रक्टर जो एक तर्क के रूप में एक ही कक्षा के संदर्भ (अधिमानतः कॉन्स्टेंट लेकिन आवश्यक नहीं) लेता है, केवल कॉपी कन्स्ट्रक्टर नाम दिया जाता है क्योंकि यह प्रभावी ढंग से करता है।

19

हां, आप एक निर्माता लिख ​​सकते हैं जो ऑब्जेक्ट में पॉइंटर लेता है। हालांकि, इसे एक कॉपी कन्स्ट्रक्टर नहीं कहा जा सकता है। एक कॉपी कन्स्ट्रक्टर के परिभाषा आपको एक ही कक्षा के ऑब्जेक्ट को पास करने की आवश्यकता है। यदि आप कुछ और गुजर रहे हैं, हाँ, यह एक कन्स्ट्रक्टर ठीक है, लेकिन प्रतिलिपि बनाने वाला नहीं है।

1

परिभाषा के अनुसार, प्रतिलिपि ctor एक कॉन्स्ट संदर्भ का उपयोग करता है। यद्यपि आपको एक संकेतक लिखने से रोकने के लिए कुछ भी नहीं है जो एक सूचक लेता है, यह किसी संदर्भ का उपयोग करते समय मौजूद कुछ समस्याएं उत्पन्न नहीं करता है - उदाहरण के लिए, यदि कोई शून्य सूचक पास हो जाता है तो क्या होना चाहिए/क्या हो सकता है?

1

एक copy constructor needs एक reference because एक value parameter Would require making एक copy, which Would invoke the copy constructor, which Would मेक एक copy की इसकी parameter, which Would invoke the copy constructor, which ...

1

आप इस तरह के एक निर्माता को लिख सकते हैं लेकिन यह तकनीकी रूप से एक प्रतिलिपि नहीं है। उदाहरण के लिए एसटीएल कंटेनर अभी भी कंपाइलर जेनरेट कॉपी कन्स्ट्रक्टर का उपयोग करेंगे (संकलक एक उत्पन्न करता है क्योंकि आपने एक नहीं लिखा था)।

2

इस तथ्य के अलावा कि यह एक कॉपी कन्स्ट्रक्टर नहीं होगा और संकलक कॉपी कन्स्ट्रक्टर उत्पन्न करेगा जबतक कि आप इसे स्पष्ट रूप से अक्षम नहीं करते हैं, हासिल करने के लिए कुछ भी नहीं है और बहुत कुछ खोना नहीं है। एक नल सूचक के बाहर एक कन्स्ट्रक्टर के लिए सही अर्थशास्त्र क्या है? यह आपकी कक्षा के उपयोगकर्ता को क्या जोड़ता है? (संकेत: कुछ भी नहीं, अगर वह एक ढेर ऑब्जेक्ट से बाहर निकलना चाहती है तो वह सिर्फ पॉइंटर को कम कर सकती है और नियमित प्रतिलिपि कन्स्ट्रक्टर का उपयोग कर सकती है)।

1

प्रतिलिपि निर्माता परोक्ष दो मामलों में प्रयोग किया जाता है:

  • अपनी कक्षा का एक उदाहरण एक समारोह के लिए मूल्य द्वारा पारित हो जाता है।
  • जब आपकी कक्षा का एक उदाहरण किसी फ़ंक्शन से मूल्य द्वारा वापस किया जाता है।

दूसरों के रूप में उल्लेख किया है, तो आप हस्ताक्षर वर्णित (या एक स्थिरांक सूचक के साथ) के साथ एक निर्माता लिख ​​सकते हैं, लेकिन यह ऊपर से किसी भी मामले में इस्तेमाल नहीं किया जाएगा।

-1

आप एक पूरी तरह से वैध प्रतिलिपि निर्माता लिख ​​सकते हैं, और फिर भी एक संदर्भ पारित करने में सक्षम हो। आप न्यूल के लिए परीक्षण कर सकते हैं, लेकिन केवल तभी जब आप कन्स्ट्रक्टर प्रारंभिक सूचियों का उपयोग नहीं करते हैं।

उदाहरण:

MyClass::MyClass(MyClass const& MyClassCopy) 
: somevar(MyClassCopy.somevar) // <- the init list goes here. 
{ 
    // If MyClassCopy is NULL, the initialization above is doomed! 
    // However we can check for NULL in the constructor body but 
    // the initialization list must be removed ... 
    if (&MyClassCopy == NULL) throw(std::runtime_error("NULL pointer!")); 
    somevar = MyClassCopy.somevar; 
} 

// I'll now do some very dangerous programming to 
// demonstrate one way that a NULL can get through ... 
MyClass* P = NULL; 
MyClass A(*P); // Bang, you're dead! 

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

मत भूलना वहाँ के साथ :: ऑपरेटर है कुछ gotchas =() के बारे में पता होना करने के लिए समारोह ...

+1

आपको लगता है कि कोड में अपरिभाषित व्यवहार लागू बिना एक अशक्त संदर्भ नहीं मिल सकता है। तथ्य के बाद न्यूल के लिए परीक्षण उपयोगी नहीं है, क्योंकि त्रुटि दूसरे कोड में है। वास्तव में, संकलक परीक्षण 'अगर (और MyClassCopy == NULL)' को अनुकूलित कर सकता है क्योंकि यह किसी भी सही प्रोग्राम में कभी नहीं हो सकता है। –

+0

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

+0

प्रतिबिंब के एक पल के बाद, आप सही हैं, आपको dereference ऑपरेशन से पहले शून्य के लिए परीक्षण करना होगा। तथ्य के बाद परीक्षण वास्तव में अपरिभाषित है। – Rob

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