असाइनमेंट ऑपरेटर और कॉपी कंस्ट्रक्टर के बीच अंतर क्या है?


105

मुझे C ++ में असाइनमेंट कंस्ट्रक्टर और कॉपी कंस्ट्रक्टर के बीच अंतर समझ में नहीं आता है। यह इस तरह है:

class A {
public:
    A() {
        cout << "A::A()" << endl;
    }
};

// The copy constructor
A a = b;

// The assignment constructor
A c;
c = a;

// Is it right?

मैं जानना चाहता हूं कि असाइनमेंट कंस्ट्रक्टर और कॉपी कंस्ट्रक्टर की मेमोरी कैसे आवंटित करें?


2
क्या आपके पास एक अच्छी C ++ पुस्तक है ?
sbi

जवाबों:


160

एक कॉपी कंस्ट्रक्टर का उपयोग किसी अन्य ऑब्जेक्ट के डेटा से पहले के अनइंस्टॉल किए गए ऑब्जेक्ट को इनिशियलाइज़ करने के लिए किया जाता है ।

A(const A& rhs) : data_(rhs.data_) {}

उदाहरण के लिए:

A aa;
A a = aa;  //copy constructor

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

A& operator=(const A& rhs) {data_ = rhs.data_; return *this;}

उदाहरण के लिए:

A aa;
A a;
a = aa;  // assignment operator

आप डिफ़ॉल्ट निर्माण प्लस असाइनमेंट द्वारा कॉपी निर्माण की जगह ले सकते हैं, लेकिन यह कम कुशल होगा।

(साइड नोट के रूप में: ऊपर दिए गए मेरे कार्यान्वयन वास्तव में कम्पाइलर अनुदानों को मुफ्त में देने वाले हैं, इसलिए उन्हें मैन्युअल रूप से लागू करने का कोई मतलब नहीं होगा। यदि आपके पास इन दोनों में से एक है, तो संभावना है कि आप मैन्युअल रूप से कुछ संसाधन का प्रबंधन कर रहे हैं। उस स्थिति में, द रूल ऑफ़ थ्री के अनुसार , आपको बहुत संभावना है कि आपको एक दूसरे को भी नष्ट करने की आवश्यकता होगी।)


4
बस एक नोट: आजकल (सी ++ 11 आगे), वे स्पष्ट रूप से डिफ़ॉल्ट रूप से हो सकते हैं =default;
डिडुप्लिकेटर

2
@Deduplicator यह उल्लेख करना भी महत्वपूर्ण है कि, वर्गीकरण के लिए जब तुच्छ कंस्ट्रक्टर की आवश्यकता होती है, तो आपको उन्हें वहाँ होना चाहिए = default जहां एक डिफ़ॉल्ट ctor की आवश्यकता होती है: बस अपने आप से एक खाली शरीर को लागू करना अभी भी उपयोगकर्ता द्वारा परिभाषित ctor के रूप में गिना जाता है और इस प्रकार (एक मानक स्तर पर) ) तुच्छ नहीं है और वर्गीकरण से उस प्रकार को अयोग्य घोषित करता है जिसे तुच्छ ctor की आवश्यकता होती है।
अंडरस्कोर_ड

@sbi क्या मैं कह सकता हूं कि यदि कॉपी कंस्ट्रक्टर का उपयोग नहीं किया जाता है और इसके बजाय असाइनमेंट ऑपरेटर का उपयोग किया जाता है, तो ऑब्जेक्ट को पहले कंस्ट्रक्टर द्वारा या तो तर्कों के साथ या बिना तर्क के बनाया जाता है और फिर असाइनमेंट ऑपरेटर का उपयोग किया जाता है और नए मानों को आरएचएस के आधार पर असाइन किया जाता है। यदि मामले में कॉपी कंस्ट्रक्टर का उपयोग किया जाता है, तब भी उसी कंस्ट्रक्टर को कॉल किया जाएगा, लेकिन आरंभीकरण के लिए उपयोग किए जाने वाले मान अन्य ऑब्जेक्ट से हैं।
राजेश

@ राजेश: आप जो पूछ रहे हैं उसके बारे में मैं उलझन में हूं, और मेरी भावना यह है कि आप भी भ्रमित हैं। :)क्या आप फिर से समझाने की कोशिश करेंगे कि आप किस बारे में बात कर रहे हैं?
sbi

1
@ CătălinaSîrbu: आप कर सकते थे। वे दो स्वतंत्र कार्य हैं।
sbi

41

कॉपी कंस्ट्रक्टर और असाइनमेंट ऑपरेटर के बीच का अंतर नए प्रोग्रामर्स के लिए बहुत भ्रम का कारण बनता है, लेकिन यह वास्तव में यह सब मुश्किल नहीं है। सारांश:

  • यदि कॉपी होने से पहले एक नई वस्तु बनाई जानी है, तो कॉपी कंस्ट्रक्टर का उपयोग किया जाता है।
  • यदि प्रतिलिपि बनाने से पहले कोई नई ऑब्जेक्ट नहीं बनाई जानी है, तो असाइनमेंट ऑपरेटर का उपयोग किया जाता है।

असाइनमेंट ऑपरेटर के लिए उदाहरण:

Base obj1(5); //calls Base class constructor
Base obj2; //calls Base class default constructor
obj2 = obj1; //calls assignment operator

कॉपी कंस्ट्रक्टर के लिए उदाहरण:

Base obj1(5);
Base obj2 = obj1; //calls copy constructor

क्या यह कहना उचित होगा कि एक असाइनमेंट ऑपरेटर एक नई वस्तु के निर्माण के साथ एक पुरानी वस्तु के विनाश को प्रभावी ढंग से जोड़ता है, लेकिन इस प्रोविसोस के साथ कि (1) यदि पुरानी वस्तु के विनाश में कोई एक कदम पूर्ववत होगा नए के निर्माण में चरणों में से एक, दोनों चरणों को छोड़ा जा सकता है; (2) असाइनमेंट ऑपरेटर्स को खराब चीजें नहीं करनी चाहिए यदि कोई ऑब्जेक्ट खुद को सौंपा गया है।
सुपरकैट

क्यों कर रहा हूँ vector <A> v3और फिर v3 = v2 (जहां v2पहले से घोषित और तत्वों से युक्त है vector<A>) मेरे स्पष्ट Aप्रति कॉपी निर्माता को कॉल करता है operator=? मैं उम्मीद कर रहा था operator=कि इसके बजाय मुझे बुलाया जाएगा copy constructorक्योंकि मेरी v3वस्तु पहले ही उस समय घोषित कर दी गई थी जब मैंने असाइनमेंट किया था
Cătălina Sărbu

19

पहली प्रतिलिपि आरंभीकरण है, दूसरी सिर्फ असाइनमेंट है। असाइनमेंट कंस्ट्रक्टर जैसी कोई चीज नहीं है।

A aa=bb;

कंपाइलर-जनरेट कॉपी कंस्ट्रक्टर का उपयोग करता है।

A cc;
cc=aa;

निर्माण करने के लिए डिफ़ॉल्ट कंस्ट्रक्टर का उपयोग करता है cc, और फिर operator =पहले से मौजूद ऑब्जेक्ट पर * असाइनमेंट ऑपरेटर ** ( )।

मुझे पता है कि असाइनमेंट कंस्ट्रक्टर और कॉपी कंस्ट्रक्टर की मेमोरी कैसे आवंटित करें?

इस मामले में स्मृति को आवंटित करने से आपका क्या मतलब है, लेकिन अगर आप देखना चाहते हैं कि क्या होता है, तो आप कर सकते हैं:

class A
{
public :
    A(){ cout<<"default constructor"<<endl;};
    A(const A& other){ cout<<"copy constructor"<<endl;};
    A& operator = (const A& other){cout <<"assignment operator"<<endl;}
};

मैं आपको यह देखने की सलाह देता हूं:

रूपांतरण कंस्ट्रक्टर के बजाय कॉपी कंस्ट्रक्टर को क्यों बुलाया जाता है?

तीन का नियम क्या है?


5

सरल शब्दों में,

कॉपी ऑब्जेक्ट तब कहा जाता है जब किसी मौजूदा ऑब्जेक्ट से एक नई ऑब्जेक्ट बनाई जाती है, मौजूदा ऑब्जेक्ट की कॉपी के रूप में। और असाइनमेंट ऑपरेटर को उस समय कहा जाता है जब पहले से ही किसी प्रारंभिक ऑब्जेक्ट को किसी अन्य मौजूदा ऑब्जेक्ट से एक नया मान सौंपा जाता है।

उदाहरण-

t2 = t1;  // calls assignment operator, same as "t2.operator=(t1);"
Test t3 = t1;  // calls copy constructor, same as "Test t3(t1);"

4

@Luchian Grigore Said को इस तरह से लागू किया जाता है

class A
{
public :
    int a;
    A(){ cout<<"default constructor"<<endl;};
    A(const A& other){ cout<<"copy constructor"<<endl;};
    A& operator = (const A& other){cout <<"assignment operator"<<endl;}
};

void main()
{
    A sampleObj; //Calls default constructor
    sampleObj.a = 10;

    A copyConsObj  = sampleObj; //Initializing calls copy constructor

    A assignOpObj; //Calls default constrcutor
    assignOpObj = sampleObj; //Object Created before so it calls assignment operator
}

आउटपुट


डिफ़ॉल्ट निर्माता


कॉपी कंस्ट्रक्टर


डिफ़ॉल्ट निर्माता


असाइनमेंट ऑपरेटर



4

कॉपी कंस्ट्रक्टर और असाइनमेंट कंस्ट्रक्टर के बीच का अंतर है:

  1. कॉपी कंस्ट्रक्टर के मामले में यह एक नई वस्तु बनाता है। ( <classname> <o1>=<o2>)
  2. असाइनमेंट कंस्ट्रक्टर के मामले में यह कोई ऑब्जेक्ट नहीं बनाएगा इसका मतलब है कि यह पहले से निर्मित ऑब्जेक्ट्स ( <o1>=<o2>) पर लागू होता है ।

और दोनों में बुनियादी कार्यक्षमताएं समान हैं, वे डेटा को o2 से o1 सदस्य-दर-सदस्य तक कॉपी करेंगे।


2

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


1

कॉपी कंस्ट्रक्टर के बारे में कुछ जोड़ना:

  • किसी वस्तु को मान से पास करते समय, यह कॉपी कंस्ट्रक्टर का उपयोग करेगा

  • जब कोई ऑब्जेक्ट किसी फ़ंक्शन से मान द्वारा लौटाया जाता है, तो वह कॉपी कंस्ट्रक्टर का उपयोग करेगा

  • किसी अन्य ऑब्जेक्ट के मूल्यों का उपयोग करके किसी ऑब्जेक्ट को इनिशियलाइज़ करते समय (उदाहरण के लिए आप जो देते हैं)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.