J'ai utilisé le code suivant pour la surcharge de l'opérateur d'affectation:
SimpleCircle SimpleCircle::operator=(const SimpleCircle & rhs)
{
if(this == &rhs)
return *this;
itsRadius = rhs.getRadius();
return *this;
}
Mon constructeur de copie est le suivant:
SimpleCircle::SimpleCircle(const SimpleCircle & rhs)
{
itsRadius = rhs.getRadius();
}
Dans le code de surcharge d'opérateur ci-dessus, le constructeur de copie est appelé car un nouvel objet est en cours de création; j'ai donc utilisé le code ci-dessous:
SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs)
{
if(this == &rhs)
return *this;
itsRadius = rhs.getRadius();
return *this;
}
Cela fonctionne parfaitement et le problème du constructeur de copie est évité, mais y a-t-il des problèmes inconnus (pour moi) à ce sujet?
Il n'y a aucun problème avec la deuxième version de l'opérateur d'affectation. En fait, c'est la méthode standard pour un opérateur d'affectation.
Edit : Notez que je fais référence au type de retour de l'opérateur d'affectation, pas à l'implémentation elle-même. Comme cela a été souligné dans les commentaires, la mise en œuvre elle-même est un autre problème. Voir ici .
Dans ces circonstances, vous feriez presque certainement mieux de ne pas cocher l'auto-affectation - lorsque vous n'affectez qu'un membre qui semble être un type simple (probablement un double), il est généralement plus rapide de faire cette affectation que d'éviter , donc vous vous retrouveriez avec:
SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs)
{
itsRadius = rhs.getRadius(); // or just `itsRadius = rhs.itsRadius;`
return *this;
}
Je me rends compte que de nombreux livres anciens et/ou de qualité inférieure conseillent de vérifier l'auto-affectation. Au moins dans mon expérience, cependant, il est suffisamment rare que vous vous en tiriez mieux sans cela (et si l'opérateur en dépend pour l'exactitude, ce n'est certainement pas une exception de sécurité).
En passant, je noterais que pour définir un cercle, vous avez généralement besoin d'un centre et d'un rayon, et lorsque vous copiez ou attribuez, vous souhaitez copier/affecter les deux.
Le second est assez standard. Vous préférez souvent renvoyer une référence à partir d'un opérateur d'affectation afin que des instructions comme a = b = c;
résoudre comme prévu. Je ne peux penser à aucun cas où je voudrais retourner une copie de la mission.
Une chose à noter est que si vous n'avez pas besoin d'une copie complète, il est parfois préférable d'utiliser le constructeur de copie implicite et l'opérateur d'affectation générés par le compilateur que de lancer le vôtre. Mais à vous de voir ...
Modifier:
Voici quelques appels de base:
SimpleCircle x; // default constructor
SimpleCircle y(x); // copy constructor
x = y; // assignment operator
Supposons maintenant que nous disposions de la première version de votre opérateur d'affectation:
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
}
Il appelle le constructeur de copie et transmet une référence à this
afin de construire la copie à renvoyer. Maintenant, dans le deuxième exemple, nous évitons la copie en renvoyant simplement une référence à 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)
}
c'est la bonne façon d'utiliser la surcharge d'opérateur maintenant que vous obtenez votre objet par référence en évitant la copie de valeur.
cela pourrait être utile:
// 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
}