2015-01-06 5 views
5

मैंने एक प्रश्नोत्तरी से मुलाकात की और कहा कि नीचे पंक्ति रेखा में कोड खराब बना हुआ है क्योंकि "एक निहित परिभाषित असाइनमेंट ऑपरेटर का उपयोग करने के लिए यह ग़लत गठित है जब सदस्यों में से एक को कॉपी करने की आवश्यकता होगी।"कक्षा का कोई सदस्य संदर्भ है तो किसी ऑब्जेक्ट की प्रतिलिपि बनाना अवैध क्यों है?

मैं इसे समझ नहीं सका। संदर्भ क्यों कॉपी नहीं किया जा सका? लाइन 16 कानूनी क्यों है? लाइन 16 लाइन 18 के बराबर है, एक कॉपी कन्स्ट्रक्टर को अभी भी कॉपी करने की ज़रूरत है, है ना?

1 #include <iostream> 
2 
3 struct A 
4 { 
5 A(int& var) : r(var) {} 
6 
7 int &r; 
8 }; 
9 
10 int main(int argc, char** argv) 
11 { 
12 int x = 23; 
13 
14 A a1(x); 
15 
16 A a2 = a1; 
17 
18 a2 = a1; 
19 
20 return 0; 
21 } 
+2

[क्या आप पूरी प्रश्नोत्तरी पोस्ट करने जा रहे हैं?] (Http://stackoverflow.com/questions/27792560/c-why-constructor-aa-a-is-illegal) – WhozCraig

+0

आह .. यह समझ में आता है। 97.4% परीक्षण बीटीडब्ल्यू पर grats। – WhozCraig

+1

अवैध * * असाइन करने के लिए *, कॉपी * नहीं *। – Potatoswatter

उत्तर

1

क्योंकि यह C++ में अवैध रूप से एक संदर्भ के लिए पुन: असाइन करने के लिए है।

int &a = some_int; 
a = some_other_int; // value copied not reference 
a = some_int; // value copied not reference 

आप प्रतिभाजन ऑपरेटर (संकलक द्वारा उत्पन्न) का उपयोग करते हैं, यह आँख बंद करके वस्तुओं की नकल करता है और इस तरह अपने संदर्भ के लिए पुन: असाइन करने की कोशिश और इसलिए अमान्य है।

जब आप कहते हैं कि a2 = a1;, संकलक यह संकलन समय पर विफल है क्योंकि यह बीमार गठन होने की पुष्टि करने के लिए a2.ra1.r पुन: असाइन करने की कोशिश करेंगे।

आप automatically dereferenced constant pointer के रूप में संदर्भ के बारे में सोच सकते हैं। तो लाइन a2 = a1; नीचे दी गई कक्षा के लिए उसी कारण से खराब प्रारूपित रहेगी।

struct A 
{ 
    A(int *var) : p(var) {} 
    int * const p; 
}; 
+3

एक संदर्भ को पुनर्जीवित करना अवैध है। इसके लिए वाक्यविन्यास भी नहीं है। हालांकि, जिसे आप अवैध मानते हैं, वह नहीं है। –

+0

आपने गलत टिप्पणी छोड़ दी है, लेकिन आपकी तर्क अभी भी गलत है, क्योंकि 'a1.r = a2.r' खराब नहीं होगा। न ही किसी अन्य संदर्भ से एक संदर्भ का प्रारंभिक रूप से गठित किया जाएगा, क्योंकि यह केवल पहले संदर्भ के संदर्भ के दूसरे संदर्भ को बांध देगा। –

+0

एक संदर्भ स्थायी रूप से अस्वीकृत सूचक की तरह है। – seand

6

लाइन 16 एक प्रति निर्माता का उपयोग करता है, लाइन 18 असाइनमेंट ऑपरेटर operator= उपयोग करता है। विभिन्न प्रतिबंधों के साथ दो अलग-अलग कार्य।

क्योंकि संदर्भ को रिबाउंड नहीं किया जा सकता है, इसलिए संकलक एक अंतर्निहित असाइनमेंट ऑपरेटर उत्पन्न नहीं कर सकता है जो किसी भी समझ में आता है। इस प्रकार यह ऐसा करने से इंकार कर देता है, और एक त्रुटि उत्पन्न करता है।

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

3

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

मानक इसलिए इस मामले को डिफ़ॉल्ट प्रतिलिपि दोनों के लिए कॉल करता है और असाइनमेंट ऑपरेटरों को ले जाता है।

सी ++ 11 § 12.8p23

दसवीं कक्षा के लिए एक डिफॉल्ट की कॉपी/कदम असाइनमेंट ऑपरेटर के रूप में नष्ट करता है, तो एक्स है परिभाषित किया गया है:

  • एक साथ एक संस्करण सदस्य गैर तुच्छ असाइनमेंट ऑपरेटर इसी और एक्स एक संघ की तरह वर्ग, या
  • एक स्थिरांक गैर वर्ग प्रकार (या उसके सरणी) की गैर स्थैतिक डेटा सदस्य, या
  • 012,351 है
  • संदर्भ प्रकार की एक गैर स्थिर डेटा सदस्य, या
  • वर्ग प्रकार एम (या उसके सरणी) के एक गैर स्थैतिक डेटा सदस्य जो कॉपी नहीं किया जा सकता है/क्योंकि अधिभार संकल्प (13 ले जाया गया।3), के रूप में एम के लिए इसी असाइनमेंट ऑपरेटर के लिए आवेदन किया, एक अस्पष्टता या एक समारोह डिफॉल्ट की असाइनमेंट ऑपरेटर से हटा दिया या दुर्गम है कि में परिणाम है, या
  • साथ सीधा या आभासी आधार वर्ग बी की प्रतिलिपि नहीं बनाई जा सकती है/क्योंकि अधिभार संकल्प ले जाया गया (13.3), बी के लिए इसी असाइनमेंट ऑपरेटर के लिए आवेदन किया के रूप में, एक अस्पष्टता या एक समारोह डिफॉल्ट की असाइनमेंट ऑपरेटर से हटा दिया या दुर्गम है कि, या
  • कदम असाइनमेंट ऑपरेटर के लिए
  • , के साथ एक गैर स्थैतिक डेटा के किसी सदस्य या प्रत्यक्ष आधार वर्ग में परिणाम एक प्रकार जिसमें एक चाल असाइनमेंट ऑपरेटर नहीं है और यह तुलनीय रूप से कॉपी करने योग्य नहीं है, या कोई प्रत्यक्ष या अप्रत्यक्ष वर्चुअल बेस क्लास नहीं है।

आप निश्चित रूप से लिख सकते हैं अधिभार।

#include <iostream> 

struct A 
{ 
    A(int& var) : r(var) {} 

    int &r; 

    A& operator=(const A& obj) 
    { 
     r = obj.r; // value copied, reference-binding remains the same 
     return *this; 
    } 
}; 

int main(int argc, char** argv) 
{ 

    int x = 42; 
    int y = 43; 

    A a1(x); 
    A a2(y); 

    A a3 = a1; // legal. default copy-ctor invoked 
    a3 = a2; // legal. user-defined copy-assignment invoked 

    std::cout << x << ',' << y << '\n'; 

    return 0; 
} 

आउटपुट

43,43 

लेकिन यह नहीं होगा (और नहीं कर सकते हैं) संदर्भ rebind। यहां प्रदान किया गया अधिभार संदर्भित डेटा बदलता है; खुद संदर्भ नहीं। ऐसा भेद महत्वपूर्ण है।

उम्मीद है कि इससे मदद मिलती है।

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

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