2010-06-21 18 views
8

एमएफसी की रूट ऑब्जेक्ट कोबजेक्ट की कॉपी कन्स्ट्रक्टर और असाइनमेंट डिफ़ॉल्ट रूप से अक्षम हैं।कोबजेक्ट की कॉपी कन्स्ट्रक्टर और असाइनमेंट को अक्षम क्यों करें

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

  • CObject के स्रोत कोड में, वहाँ एक टिप्पणी है:

प्रतिलिपि निर्माता और डिफ़ॉल्ट रूप से काम अक्षम ताकि आप अप्रत्याशित व्यवहार के बजाय संकलक त्रुटियों यदि आप द्वारा वस्तुओं पारित हो जाएगा मूल्य या वस्तुओं को असाइन करें।

मेरा प्रश्न है, इस कॉब्जेक्ट क्लास के लिए डिफ़ॉल्ट बिट-बाय-बिट कॉपी कन्स्ट्रक्टर के साथ समस्या क्या है? मेरी राय में, यह हमारे डिफ़ॉल्ट प्रतिलिपि निर्माता देने के लिए बेहतर होगा, और यदि आवश्यक (गहरी प्रतिलिपि)

+0

अधिक उपयोगकर्ताओं को आकर्षित करने के लिए एमएफसी टैग को बेहतर ढंग से हटाएं –

+1

उत्तर एमएफसी विशिष्ट होने की संभावना है, हालांकि। – peterchen

+0

धन्यवाद, यह काम करता है !!! –

उत्तर

6

डिफ़ॉल्ट प्रतिलिपि निर्माता सदस्य-दर-सदस्य, नहीं बिटवाइज़ है।

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

उदा उपलब्ध कराने के एक "सही" प्रतिलिपि निर्माता आश्चर्यजनक रूप से कठिन और महंगा है,

class CGDIObject : public CObject 
{ 
    HGDIOBJ m_handle; 

    CGDIObject() : m_handle(0) {} 
    // derived classes provide a create, attach etc. 
    ~CGDIObject() { DeleteObject(m_handle); } 
} 

यहाँ डिफ़ॉल्ट प्रतिलिपि निर्माता खतरनाक होगा (डबल विनाश के लिए अग्रणी): CGDIObject मोटे तौर पर है।

एक और कारण यह हो सकता है कि अधिकांश कोबजेक्ट-व्युत्पन्न कक्षाओं को उत्परिवर्तित करने का इरादा है, और इस प्रकार संदर्भ द्वारा पारित किया जाता है।एक लापता प्रतिलिपि निर्माता अनायास ही प्रतियां हैं, जिन्हें एक प्रति के बजाय वस्तु पारित कर दिया उत्परिवर्तित पकड़ेगा:

class CMyObject : public CObject 
{ 
    public: 
     AttachFoo(FooHandle foo) { ... } 
     AddBar() { ... } 
}; 

bool InitMySession(CMyObject & obj) 
{ 
    obj.AttachFoo(CreateRawFoo()); 
    obj.AddBar(); 
    obj.AddBar(); 
} 

// ... 
CMyObj mo; 
InitMySession(mo); 

छोड़ना "&" आप कोड है कि अच्छी तरह से संकलित देता है, लेकिन अस्थायी प्रतिलिपि बनाता है, कि संशोधित करता है और यह चला जाता है , जबकि mo असम्बद्ध है।

काफी कई एपीआई कि पैटर्न का पालन, के रूप में MFC से निपटने त्रुटि के लिए अपवाद पर निर्भर नहीं करता (ऐतिहासिक कारणों के लिए: नहीं सभी लक्षित compilers उन्हें अच्छी तरह से समर्थन किया था, और MFC कि अपवादों के साथ दर्दनाक हो जाता है अतिरिक्त संसाधन से निपटने का एक बहुत आवश्यकता है)।


मुझे नहीं लगता कि ये विकल्प अच्छे हैं, उदा। व्युत्पन्न कक्षाओं को डिफ़ॉल्ट प्रतिलिपि बनाने वाले को उपयोग करने की अनुमति दी जानी चाहिए यदि उनके सदस्य अनुमति देते हैं (और अधिकांश सदस्यों को अनुमति देनी चाहिए)।

निर्णय एमएफसी की "मानसिकता" फिट बैठता है, हालांकि, एमएफसी के समय के पुनर्मूल्यांकन/प्रतिबंध।

+0

अच्छा बिंदु, एमएफसी और उन सिस्टम संसाधनों के बीच घनिष्ठ संबंध उन्हें ऐसा करने का फैसला कर सकता है। मैं तुम्हारा दूसरा बिंदु बिल्कुल समझ नहीं पाया, उत्परिवर्ती की बात करते समय आपका क्या मतलब है? –

+0

अधिक जानकारी जोड़ा गया – peterchen

3

निम्नलिखित पर विचार करें हम एक प्रदान कर सकता है:

class CMyHandle : public CObject 
{ 
    HANDLE hWin32; 
public: 
    CMyHandle() 
    { 
     hWin32 = SomeFunctionThatMakesHandle(); 
    } 
    ~CMyHandle() 
    { 
     CloseHandle(hWin32); 
    } 
}; 

अब, अगर आप CMyHandle, कॉपी हैंडल दो बार बंद हो जाता है, और CMyHandle में से किसी एक के बाद नष्ट हो जाता है, दूसरा उदाहरण अमान्य हो जाता है।

चूंकि बड़ी संख्या में एमएफसी कक्षाएं हैंडल प्रबंधित करती हैं, इसलिए यह समझता है कि कक्षा के निर्माता को कॉपी कन्स्ट्रक्टर बनाने और असाइनमेंट ऑपरेटर कॉपी करने के लिए स्पष्ट रूप से ओवरराइड करने के लिए मजबूर किया जाता है।

संपादित करें: उदाहरण के लिए:

int main() 
{ 
    CMyHandle h1; //CMyHandle's constructor initializes the handle 
    { 
     CMyHandle h2(h1); //Memberwise copy into h2. In this case, it copies the 
          //handle 
    } //h2 destroyed, closes handle 
    //h1 is now invalid (because the underlying handle was closed)! 
} 
संबंधित मुद्दे

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