2012-04-09 8 views
20

मैं काम ऑपरेटर ओवरलोडिंग के लिए निम्न कोड का इस्तेमाल किया है में अधिक भार:असाइनमेंट ऑपरेटर C++

SimpleCircle::SimpleCircle(const SimpleCircle & rhs) 
{ 
    itsRadius = rhs.getRadius(); 
} 

ऊपर ऑपरेटर ओवरलोडिंग कोड में, नकल निर्माता कहा जाता है:

SimpleCircle SimpleCircle::operator=(const SimpleCircle & rhs) 
{ 
    if(this == &rhs) 
     return *this; 
    itsRadius = rhs.getRadius(); 
    return *this; 
} 

मेरे कॉपी निर्माता यह है क्योंकि एक नई वस्तु बनाई जा रही है;

SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs) 
{ 
    if(this == &rhs) 
     return *this; 
    itsRadius = rhs.getRadius(); 
    return *this; 
} 

इसकी पूरी तरह से काम कर रहा है और प्रति निर्माता समस्या से बचा जाता है, लेकिन वहाँ किसी भी अज्ञात मुद्दों (मेरे लिए) इस बारे में है: इसलिए मैं नीचे दिए गए कोड का इस्तेमाल किया?

+0

[कॉपी और स्वैप मुहावरा] पर एक नज़र (http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap ले लो -idiom) – Praetorian

+1

@Praetorian कॉपी और स्वैप मुहावरे अच्छा है अगर आपको पता है कि कोई आइटम असाइनमेंट ऑपरेटर के दौरान फेंक सकता है या यदि आप सॉफ़्टवेयर के साथ काम कर रहे हैं तो आपने विकसित नहीं किया है और पता नहीं है कि कोई फेंक होगा या नहीं। यदि आप अपने सामानों के साथ काम कर रहे हैं और आपको पता है कि प्रतिलिपि का उपयोग करके कोई फेंकता नहीं होगा और स्वैप मुहावरे आवश्यक नहीं है। –

उत्तर

10

असाइनमेंट ऑपरेटर के दूसरे संस्करण के साथ कोई समस्या नहीं हैं। वास्तव में, यह एक असाइनमेंट ऑपरेटर के लिए मानक तरीका है।

संपादित करें: ध्यान दें कि मैं असाइनमेंट ऑपरेटर के रिटर्न प्रकार का जिक्र कर रहा हूं, न कि कार्यान्वयन के लिए। जैसा कि टिप्पणियों में बताया गया है, कार्यान्वयन स्वयं एक और मुद्दा है। here देखें।

+3

दरअसल मानक तरीका है * कॉपी और स्वैप * विधि का उल्लेख नहीं किया गया है। –

+1

@Als: रिमोट स्वामित्व से निपटने की आवश्यकता होने पर कॉपी और स्वैप निश्चित रूप से मानक है। एक एकल, सरल मूल्य से निपटने पर मैं इसे ओवरकिल कहूंगा (हालांकि अभी भी सवाल में क्या बेहतर है)। –

+0

@ जेरीकॉफिन: असल में, मैं एकल मूल्यवान कॉल के लिए वकील प्रतिलिपि और स्वैप करता हूं क्योंकि एक बार जब आप इसे सही तरीके से करना सीख चुके हैं तो प्रतिलिपि बनाना और स्वैप करना मुश्किल है। –

4

दूसरा सुंदर मानक है। आप अक्सर ताकि a = b = c; संकल्प जैसे बयानों की उम्मीद के रूप में एक असाइनमेंट ऑपरेटर से एक संदर्भ वापस जाने के लिए पसंद करते हैं। मैं किसी भी मामले के बारे में नहीं सोच सकता जहां मैं असाइनमेंट से प्रतिलिपि वापस करना चाहता हूं।

ध्यान देने योग्य एक बात यह है कि यदि आपको गहरी प्रतिलिपि की आवश्यकता नहीं है तो इसे कभी-कभी संकलक द्वारा उत्पन्न निहित प्रतिलिपि निर्माता और असाइनमेंट ऑपरेटर का उपयोग करने के लिए सबसे अच्छा माना जाता है। वास्तव में आप हालांकि अप करने के लिए ...

संपादित करें:

यहाँ कुछ बुनियादी कॉल:

SimpleCircle x; // default constructor 
SimpleCircle y(x); // copy constructor 
x = y; // assignment operator 

अब कहते हैं कि हम अपने असाइनमेंट ऑपरेटर का पहला संस्करण था:

SimpleCircle SimpleCircle::operator=(const SimpleCircle & rhs) 
{ 
    if(this == &rhs) 
     return *this; // calls copy constructor SimpleCircle(*this) 
    itsRadius = rhs.getRadius(); // copy member 
    return *this; // calls copy constructor 
} 

यह प्रतिलिपि निर्माता कॉल करता है और आदेश की नकल के निर्माण के लिए में this के लिए एक संदर्भ वापस करने से गुजरता है। जब आप केवल एक सौंप कर रहे हैं - अब दूसरे उदाहरण में हम सिर्फ परिस्थितियों में this

SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs) 
{ 
    if(this == &rhs) 
     return *this; // return reference to this (no copy) 
    itsRadius = rhs.getRadius(); // copy member 
    return *this; // return reference to this (no copy) 
} 
+0

दरअसल मैं यह सुनिश्चित करना चाहता था कि इस प्रतिलिपि निर्माता कहां कहलाए जा रहे हैं। मैं एक cout का उपयोग कर रहा हूँ << "मुझे बुलाया जा रहा है"; उस में। केवल समस्या का कारण बनना। यह मूल्यों की प्रतिलिपि नहीं बना रहा है। – kaushik

+0

मैं आपके पहले उदाहरण में मूल्य द्वारा प्रतिलिपि वापस करने का जिक्र कर रहा था। – AJG85

5

के लिए एक संदर्भ वापस लौट कर नकल से बचने के लिए, आप लगभग निश्चित रूप से स्वयं काम के लिए चेक लंघन से बेहतर कर रहे हैं सदस्य दिखाई देती है कि एक साधारण प्रकार (शायद एक डबल), यह है कि यह से बचने से काम करने के लिए आम तौर पर तेजी है होना करने के लिए है, तो आप को रखना होगा:

SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs) 
{ 
    itsRadius = rhs.getRadius(); // or just `itsRadius = rhs.itsRadius;` 
    return *this; 
} 

मैं कई है कि पुराने और/या कम गुणवत्ता का एहसास पुस्तकें स्वयं असाइनमेंट की जांच करने की सलाह देते हैं। मेरे अनुभव में कम से कम, फिर भी, यह पर्याप्त रूप से दुर्लभ है कि आप इसे बिना बेहतर कर रहे है (और अगर ऑपरेटर शुद्धता के लिए उस पर निर्भर करता है, यह लगभग निश्चित रूप से नहीं अपवाद सुरक्षित है)।

एक के रूप में अलग रूप में, मैं ध्यान दें चाहते हैं कि एक चक्र को परिभाषित करने के लिए, आप आम तौर पर एक केंद्र और एक त्रिज्या की जरूरत है, और जब आप कॉपी या असाइन करते हैं, आप कॉपी/दोनों प्रदान करना चाहते हैं।

0

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

-1

इस उपयोगी हो सकता है:

// Operator overloading in C++ 
//assignment operator overloading 
#include<iostream> 
using namespace std; 

class Employee 
{ 
private: 
int idNum; 
double salary; 
public: 
Employee () { 
    idNum = 0, salary = 0.0; 
} 

void setValues (int a, int b); 
void operator= (Employee &emp); 

}; 

void Employee::setValues (int idN , int sal) 
{ 

salary = sal; idNum = idN; 

} 

void Employee::operator = (Employee &emp) // Assignment operator overloading function 
{ 
salary = emp.salary; 
} 

int main () 
{ 

Employee emp1; 
emp1.setValues(10,33); 
Employee emp2; 
emp2 = emp1; // emp2 is calling object using assignment operator 

} 
+3

यदि आप केवल कोड स्निपेट पोस्ट करने के बजाय पोस्ट कोड स्निपेट में महत्वपूर्ण क्षेत्रों को समझा सकते हैं, तो यह अधिक सहायता हो सकती है। – RinoTom