2013-06-20 4 views
20

इस कोड:मुझे एक अस्थिर से डिफ़ॉल्ट प्रतिलिपि निर्माता क्यों प्रदान नहीं किया गया है?

class X { 
    int member; 
}; 

volatile X a; 
X b = a; 

त्रुटि के साथ विफल:

prog.cpp:6:7: error: no matching function for call to ‘X::X(volatile X&)’ 
prog.cpp:6:7: note: candidates are: 
prog.cpp:1:7: note: X::X() 
prog.cpp:1:7: note: candidate expects 0 arguments, 1 provided 
prog.cpp:1:7: note: X::X(const X&) 
prog.cpp:1:7: note: no known conversion for argument 1 from ‘volatile X’ to ‘const X&’ 

वहाँ किसी भी तरह से मैं संकलक मेरे लिए एक अस्थिर प्रतिलिपि निर्माता उत्पन्न करने के लिए प्राप्त कर सकते हैं है?

+0

आप की जरूरत है 'बी' वाष्पशील घोषित करने के लिए। – 0x499602D2

+0

लेकिन मुझे एक अस्थिर प्रतिलिपि चाहिए! – Eric

+3

'अस्थिर एक्स और' को 'कॉन्स्ट एक्स' में परिवर्तित नहीं किया जा सकता क्योंकि दोनों क्वालीफायर एक-दूसरे से विरोधाभास करते हैं: 'कॉन्स' कहता है, "इसे एक बार पढ़ें, यह बदलने वाला नहीं है", जबकि 'अस्थिर' कहता है, "इसे हर बार पढ़ें, क्योंकि यह बदल सकते हैं"। सी ++ मानक में कुछ स्मार्ट नियम होना चाहिए जो इस रूपांतरण को पूरी तरह से प्रतिबंधित करने पर रोक लगाता है। – dasblinkenlight

उत्तर

14

संक्षिप्त उत्तर यह है: क्योंकि मानक कहता है कि आप नहीं करेंगे।

सी ++ मानक 12।8/9 (ड्राफ्ट N3242) बताता है:

The implicitly-declared copy constructor for a class X will have the form

  • X::X(const X&)

if

  • each direct or virtual base class B of X has a copy constructor whose first parameter is of type const B& or const volatile B&, and
  • for all the non-static data members of X that are of a class type M (or array thereof), each such class type has a copy constructor whose first parameter is of type const M& or const volatile M&. [Note: 119]

Otherwise, the implicitly-declared copy constructor will have the form

  • X::X(X&)

नोट 119 का कहना है:

This implies that the reference parameter of the implicitly-declared copy constructor cannot bind to a volatile lvalue; see C.1.9.

C.1.9 में आप मिल जाएगा:

The implicitly-declared copy constructor and implicitly-declared copy assignment operator cannot make a copy of a volatile lvalue. For example, the following is valid in ISO C:

struct X { int i; }; 
volatile struct X x1 = {0}; 
struct X x2(x1); // invalid C++ 
struct X x3; 
x3 = x1; // also invalid C++ 

Rationale: Several alternatives were debated at length. Changing the parameter to volatile const X& would greatly complicate the generation of efficient code for class objects. Discussion of providing two alternative signatures for these implicitly-defined operations raised unanswered concerns about creating ambiguities and complicating the rules that specify the formation of these operators according to the bases and members.

-3

मुख्य समस्या यह है कि आप असाइनमेंट कन्स्ट्रक्टर प्रदान नहीं करते हैं। नतीजतन, संकलक एक डिफ़ॉल्ट आप के लिए एक उत्पन्न:

X& X::operator =(const X& x){ 
    this.member = x.member; 
    return *this; 
} 

डिफ़ॉल्ट असाइनमेंट निर्माता स्थिरांक के रूप में तर्क प्रकार स्वीकार करता है एक्स & जिसमें स्थिरांक एक निम्न स्तर स्थिरांक है और जीता " शीर्ष-स्तरीय कॉस्ट के रूप में अनदेखा किया जाएगा।

आपका कोड X b = a डिफ़ॉल्ट कन्स्ट्रक्टर को कॉल करने का मतलब है। लेकिन अपने तर्क a टाइप अस्थिर एक्स (अस्थिर एक्स & और अस्थिर स्थिरांक एक्स & में बदला जा सकता) स्थिरांक एक्स & परोक्ष में परिवर्तित नहीं किया जा सकता है।

तो आप अपने खुद के काम के निर्माता परिभाषित करना चाहिए

X& X::operator =(volatile const X&); 

संपादित के रूप में
यह मेरे झटके इतने लोग लगता है कि प्रतिलिपि निर्माता (या फोन प्रतिलिपि प्रारंभ) है असाइनमेंट ऑपरेटर का उपयोग करते समय कहा जाता है। शायद इसे असाइनमेंट ऑपरेटर पर कॉल करना आम नहीं है। हालांकि, मुझे क्या ख्याल है कि किस विधि को बुलाया जाता है।

इस पोस्ट का उल्लेख कर सकते हैं: Copy constructors, assignment operators, and exception safe assignment और Default assignment operator


संपादित
मैं पहले एक गलती की है। X b = a सिर्फ एक प्रारंभिक प्रक्रिया है। कोई असाइनमेंट शामिल नहीं है। मेरे त्रुटि संदेश के लिए क्षमा मांगें।

+3

नहीं। 'एक्स (अस्थिर कॉन्स एक्स और एक्स) जैसे एक कन्स्ट्रक्टर: सदस्य (x.member) {}' की आवश्यकता होगी क्योंकि 'एक्स बी = ए;' प्रति-प्रारंभिक है। "असाइनमेंट कन्स्ट्रक्टर" जैसी कोई चीज़ नहीं है। या तो एक कन्स्ट्रक्टर या असाइनमेंट ऑपरेटर है। – Pixelchemist

+0

@ पिक्सेलकेमिस्ट जो आप प्रदान करते हैं उसे "कॉपी कन्स्ट्रक्टर" कहा जाता है। ये दोनों अलग-अलग चीजें हैं। इसे सी ++ में ** ** ** का नियम कहा जाता है। – Zachary

+0

तीन का नियम मुख्य रूप से संसाधनों के प्रबंधन के वर्गों पर लागू होता है। इस मामले में अस्थिर एक्स से एक्स – Pixelchemist

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