2012-04-09 19 views
20

ich den folgenden Code für Zuweisungsoperator Überlastung verwendet haben:Zuweisungsoperator in c Überlastung ++

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

My Copy Constructor ist dies:

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

In dem obigen Betreiber Überlastung Code, Copy-Konstruktor aufgerufen wird da wird ein neues Objekt erschaffen; daher habe ich den folgenden Code:

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

Seine gut funktionierend und das Kopierkonstruktor Problem vermieden wird, aber ist es unbekannte Probleme (für mich) in Bezug auf das?

+0

Werfen Sie einen Blick auf die [Kopie und Swap-Idiom] (http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap -idiom) – Praetorian

+1

@Praetorian Das Kopier- und Tausch-Idiom ist gut, wenn Sie wissen, dass ein Element während des Zuweisungsoperators geworfen werden kann oder wenn Sie mit Software arbeiten, die Sie nicht entwickelt haben und nicht wissen, ob ein Wurf auftreten wird. Wenn du mit deinen eigenen Gegenständen arbeitest und du weißt, dass es keine Würfe geben wird, die das Kopieren und das Tausch-Idiom verwenden, ist das nicht notwendig. –

Antwort

10

Es gibt keine Probleme mit der zweiten Version des Zuweisungsoperators. In der Tat ist das der Standard für einen Zuweisungsoperator.

Bearbeiten: Beachten Sie, dass ich auf den Rückgabetyp des Zuweisungsoperators beziehen, nicht auf die Implementierung selbst. Wie in den Kommentaren erwähnt wurde, ist die Implementierung selbst ein anderes Thema. Siehe here.

+3

Eigentlich ist die Standardmethode * Copy & Swap * Methode nicht die eine erwähnt. –

+1

@Als: Kopieren und Tauschen ist sicherlich Standard, wenn Sie mit Remote-Besitz beschäftigen müssen. Wenn ich mit einem einzigen, einfachen Wert handle, würde ich es als Overkill bezeichnen (obwohl es wahrscheinlich immer noch besser ist als das, was in der Frage steht). –

+0

@JerryCoffin: Eigentlich befürworte ich Kopieren und Swap für single-valued Call, weil es schwer ist, kopieren und tauschen, sobald Sie gelernt haben, es richtig zu machen. –

4

Die zweite ist ziemlich Standard. Oft ziehen Sie es vor, eine Referenz von einem Zuweisungsoperator zurückzugeben, damit Anweisungen wie a = b = c; wie erwartet aufgelöst werden. Ich kann mir keine Fälle vorstellen, in denen ich eine Kopie vom Auftrag zurückgeben möchte.

Eine Sache zu beachten ist, dass, wenn Sie keine tiefe Kopie benötigen, es manchmal am besten ist, den impliziten Kopierkonstruktor und den Zuweisungsoperator zu verwenden, der vom Compiler erzeugt wird, als Ihren eigenen zu rollen. Wirklich an Ihnen aber ...

Edit:

Hier einige grundlegende Anrufe:

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

Nun sagen wir die erste Version des Zuweisungsoperator hatte:

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 
} 

Es ruft den Kopierkonstruktor auf und übergibt eine Referenz an this, um die Kopie zu erstellen, die zurückgegeben werden soll. Jetzt im zweiten Beispiel vermeiden wir die Kopie nur durch einen Verweis auf 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

Eigentlich wollte ich sicherstellen, wo dieser Kopierkonstruktor aufgerufen wird. Ich benutze einen Cout << "Ich werde angerufen"; darin. Nur mit dem, was Probleme verursacht. Es kopiert keine Werte. – kaushik

+0

Ich bezog mich auf die Rückgabe einer Kopie nach Wert in Ihrem ersten Beispiel. – AJG85

5

Unter den Umständen der Rückkehr, sind Sie fast sicher besser die Prüfung für Selbstzuordnung Überspringen - wenn Sie nur eine Zuordnung Element, das es als vermeiden ein einfacher Typ (wahrscheinlich ein Doppelzimmer), ist es im allgemeinen schneller zu tun, dass die Zuordnung zu sein scheint, so würden Sie am Ende mit:

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

ich weiß, dass viele ältere und/oder geringere Qualität Bücher raten zur Selbstüberprüfung. Zumindest ist es meiner Erfahrung nach jedoch selten genug, dass es ohne sie besser geht (und wenn der Operator von der Korrektheit abhängt, ist es fast sicher nicht ausnahmslos sicher).

Als Nebenbemerkung würde ich bemerken, dass Sie zum Definieren eines Kreises in der Regel einen Mittelpunkt und einen Radius benötigen, und wenn Sie kopieren oder zuweisen, möchten Sie beide kopieren/zuweisen.

0

es ist richtige Weise, Operator Überladung zu verwenden jetzt erhalten Sie Ihr Objekt durch Referenz vermeiden Wert kopieren.

-1

könnte dies nützlich sein:

// 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

Es kann hilfreicher sein, wenn Sie die Schlüsselbereiche im Code-Snippet erklären können, anstatt einfach nur ein Code-Snippet zu posten. – RinoTom