2012-04-09 22 views
20

He utilizado el siguiente código para la sobrecarga de operadores de asignación:operador de asignación sobrecarga en C++

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

Mi constructor de copia es la siguiente:

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

En el código de operador por encima de la sobrecarga, constructor de copia se llama ya que hay un nuevo objeto que se está creando; por lo tanto, he utilizado el código de abajo:

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

Su funcionando perfectamente y el problema se evita constructor de copia, pero ¿hay algún problema desconocido (para mí) con respecto a esto?

+0

Tome un vistazo a la [copia, intercambio de idioma] (http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap -idiom) – Praetorian

+1

@Praetorian La copia y el cambio de idioma son buenos si sabe que un artículo puede arrojarse durante el operador de asignación o si está trabajando con un software que no ha desarrollado y no sabe si ocurrirá un lanzamiento. Si está trabajando con sus propios artículos y sabe que no habrá tiros usando la copia y el intercambio de expresiones idiomáticas, no es necesario. –

Respuesta

10

No hay problemas con la segunda versión del operador de asignación. De hecho, esa es la forma estándar para un operador de asignación.

Editar: Tenga en cuenta que me refiero al tipo de devolución del operador de asignación, no a la implementación en sí. Como se ha señalado en los comentarios, la implementación en sí es otro problema. Ver here.

+3

En realidad, la forma estándar es el método * Copy & Swap * no mencionado. –

+1

@Als: Copiar y cambiar es ciertamente estándar cuando necesita tratar con propiedad remota. Cuando se trata de un único valor simple, lo llamaría excesivo (aunque probablemente sea mejor que lo que está en la pregunta). –

+0

@JerryCoffin: De hecho, yo defiendo Copy and Swap para llamadas de un solo valor porque es difícil estropear copiar y cambiar una vez que has aprendido a hacerlo de la manera correcta. –

4

El segundo es bastante estándar. A menudo prefiere devolver una referencia de un operador de asignación para que las declaraciones como a = b = c; se resuelvan como se esperaba. No puedo pensar en ningún caso en el que me gustaría devolver una copia de la tarea.

Una cosa a tener en cuenta es que si no necesita una copia profunda a veces se considera mejor utilizar el constructor de copia implícita y el operador de asignación generado por el compilador que el propio. Realmente depende de ti, aunque ...

Editar:

Aquí hay algunas llamadas básicas:

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

Ahora decir que tuvimos la primera versión de su operador de asignación:

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 
} 

Llama al constructor de copia y pasa una referencia al this para construir la copia que se devolverá. Ahora bien, en el segundo ejemplo se evita la copia que acaban de volver una referencia a 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

En realidad, quería asegurarme de que se llame a este constructor de copia. Estoy usando un cout << "Me están llamando"; en eso. Solo usando eso causando problemas. No está copiando valores. – kaushik

+0

Me refería a devolver una copia por valor en su primer ejemplo. – AJG85

5

Dadas las circunstancias, usted es casi seguro que mejor saltarse la comprobación de auto-asignación - cuando sólo se está aplicando una miembro que parece ser un tipo simple (probablemente una doble), que es generalmente más rápido que hacer que la asignación de evitarlo, por lo que acabaría con:

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

Soy consciente de que muchos de los antiguos y/o de menor calidad los libros recomiendan verificar la auto asignación. Sin embargo, al menos, en mi experiencia, es lo suficientemente raro como para estar mejor sin él (y si el operador depende de ello para ser correcto, es casi seguro que no es una excepción).

Como nota aparte, me gustaría señalar que para definir un círculo, generalmente necesita un centro y un radio, y cuando copia o asigna, desea copiar/asignar ambos.

0

es manera correcta de utilizar la sobrecarga del operador ahora obtiene su objeto por referencia evitando copiar valor.

-1

esto podría ser útil:

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

Puede ser de más ayuda si puede explicar las áreas clave en el fragmento de código publicado, que simplemente publicar un fragmento de código así. – RinoTom