10

यह सही ढंग से समझने के लिए बस एक त्वरित सवाल है जब आप इस तरह एक निर्माता के साथ एक वर्ग बनाने के क्या होता है:संकलक उत्पन्न कंस्ट्रक्टर्स

class A 
{ 
    public: 
    A() {} 
}; 

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

class A 
{ 
    private: 
    // needed to prevent automatic generation? 
    A(const A&); 
    A& operator=(const A&); 
    public: 
    A() {} 
}; 

उत्तर

10

हां। कॉपी कन्स्ट्रक्टर, असाइनमेंट ऑपरेटर, और विनाशक हमेशा अन्य रचनाकारों और ऑपरेटरों के बावजूद बनाए जाते हैं।

यदि आप एक को अक्षम करना चाहते हैं, तो आपको जो मिला है वह सही है। यह भी काफी आम है।

+0

दरअसल छिपा नहीं होगा, हालांकि यदि आप इस, कॉपी/काम को रोकने की जाँच करने के लिए उपयोग कर रहे हैं [बढ़ावा देने :: noncopyable] (http: // www .boost.org/doc/libs/1_55_0/libs/उपयोगिता/utility.htm # Class_noncopyable)। (आप इस साधारण वर्ग को बाहर निकाल सकते हैं या अपना खुद का लिख ​​सकते हैं और जहां भी चाहें इसका पुन: उपयोग कर सकते हैं।) – TypeIA

13

हां, कॉपी कन्स्ट्रक्टर और कॉपी असाइनमेंट ऑपरेटर अभी भी बनाए गए हैं भले ही आप अपना खुद का डिफॉल्ट कन्स्ट्रक्टर घोषित करें।

उन लोगों का निर्माण केवल तभी दबाया जाता है जब आप क्रमशः कक्षा परिभाषा में अपनी प्रतिलिपि निर्माता या कॉपी असाइनमेंट ऑपरेटर घोषित करते हैं।

ध्यान दें कि यह दोनों अपनी स्वयं की प्रतिलिपि निर्माता, और एक प्रदान की एक संकलक करना संभव है:

struct A { 
    A() { } 
    A(A const&, int foo); 
}; // compiler declares a copy constructor now 

// make the second parameter have a default argument 
// now this constructor is a copy constructor too. 
inline A::A(A const&, int foo = 0) { 

} 

int main() { 
    A a; 
    A b = a; // ambiguity between compiler's one and our custom one! 
} 

स्टैंडर्ड तथापि compilers इस कोड को स्वीकार करने के लिए अनुमति देता है - लेकिन प्रभाव अपरिभाषित व्यवहार होने के समान है: कार्यक्रम खराब है, लेकिन उस कार्यक्रम के लिए कोई चेतावनी/त्रुटि की आवश्यकता नहीं है। (प्रारंभिक जीसीसी संस्करण इस कोड को अस्वीकार नहीं करते हैं, हाल ही में इसे अस्वीकार कर दिया गया है)।

+1

आपकी पोस्ट "सामान्य रूप में" बहुत ही जानकारीपूर्ण हैं :) –

2

यदि आप प्रतिलिपि और असाइन करना अक्षम करना चाहते हैं, तो एक ऐसे वर्ग से उत्तराधिकारी होना बेहतर हो सकता है जिसमें एक निजी प्रतिलिपि निर्माता और असाइनमेंट ऑपरेटर है (boost::noncopyable तैयार तैयार है)।

1) कम दोहराव टाइपिंग।

2) स्वयं-दस्तावेज (उम्मीद है)।

3) मजबूत जांच करता है कि उन परिचालनों को लागू नहीं किया जा सकता है (कक्षा स्वयं, न ही मित्र प्रतियां बना सकते हैं - जिसके परिणामस्वरूप एक कंपाइलर होगा, लिंकर त्रुटि नहीं)।

4), डिफ़ॉल्ट निर्माता :)

#include <boost/noncopyable.hpp> 

class X : boost::noncopyable 
{ 
}; 

int main() 
{ 
    X a, b;  //has default constructor 
    //X c(a); //but can't be copied 
    //a = b; //or assigned 
}