Pregunta

Estoy escribiendo una biblioteca matemática como un ejercicio práctico. Me he encontrado con algunos problemas cuando se sobrecarga el operador =. Cuando debuged, me di cuenta de que la llamada a vertex1 = vertex2 llama al constructor de copia en su lugar.

En el archivo de cabecera que tengo:

//constructors
vector3();
vector3( vector3 &v );
vector3(float ix, float iy, float iz);

//operator overloading
vector3 operator =(vector3 p);
....

En el archivo de origen implementé:

vector3 vector3::operator =(vector3 p)
{
    vector3 v3;
    v3.x = p.x;
    v3.y = p.y;
    v3.z = p.z;
    return v3;
}

Más tarde tengo un método de productos cruzados, y yo quiero usarlo de esta manera:

vector3 v3;
v3 = v1.crossProduct(v2);

El mensaje de error es:     Error: ninguna función coincidente para la llamada a `vector3 :: vector3 (vector3)' pero yo no quiero llamar al constructor de copia.

¿Fue útil?

Solución

Hay errores en el código. Su constructor de copia debe tomar un const&. La referencia será evitar hacer una copia (que no sería capaz de hacer, siendo el constructor de copia), y debe ser const ya que no está modificándolo:

vector3(const vector3&);

Las variables temporales se pueden unir a const&, pero no pueden pueden unir a una referencia mutable. Es decir, con el código que podría hacer:

vector3 a;
vector3 b(a);

pero no:

vector3 a(some_calculation()); // some_calculation returns a vector3

Además, su operator= es incorrecta. Al igual que el constructor de copia, debería generalmente dar un const&, pero debe devolver una referencia a this . Así es como funciona el encadenamiento:

int a, b, c;
a = b = c = 0;
// a.operator=(b.operator=(c.operator=(0)));

La devolución de un temporal es poco ortodoxo, y no logra nada. En su caso, podría asignar una y otra vez y nunca cambiar el valor. Extraño

vector 3 a, b;
a = b; // doesn't change a...?!

operator= necesita cambiar this.

Otros consejos

  
    

vector3 (vector3 & v);

  

Esto realmente debe ser vector3( const vector3 &v );

Desde el retorno de un valor temporal, debe llamar a un constructor de copia que tiene una referencia constante.

  

No quiero llamar al constructor de copia.

Lo que queremos es irrelevante. Usted necesidad un constructor de copia aquí. operator = no consigue llamado en esta situación, el constructor de copia es. Además, la firma es incorrecta, debería ser

vector3& operator =(vector3 const& other);

El argumento también se puede pasar en términos de valor (pero esto es un truco avanzado ...) pero el valor de retorno realmente debe sea una referencia no const.

(La firma de su constructor de copia también es poco convencional, véase la respuesta de James.)

Hacer referencias de uso vector3 vector3::operator =(vector3 p) lugar por lo que no es necesario crear una copia.

vector3& vector3::operator =(vector3& p);

Usted no desea crear un objeto copiado en el primer lugar de todos modos.

Es una buena práctica en C ++ para hacer una de dos cosas, dependiendo de si usted quiere que su copiable objeto (es decir asignable a otra variable) o no. Si usted necesita para proporcionar tanto el operador de asignación y el constructor de copia. Por ejemplo:

class Point
{
public:
    Point ()                          { }
    Point (int x, int y)              : mX(x), mY(y) { }
    Point (const Point& p)            : mX(p.mX), mY(p,mY) { }

    Point& operator = (const Point& p)    { mX = p.mX; mY = p.mY; return *this; }

    int X () const                    { return mX; }
    int Y () const                    { return mY; }

private:
    int mX;
    int mY;
};

Si no desea que copiable se puede poner el prototipo tanto del constructor de copia y el operador de asignación en una sección privada y no proporcionan una implementación. Cualquier intento de copiar a continuación se dará un error de compilación.

Siempre que utilice este tipo de código:

Point P = anotherP;

el constructor de copia se llamará. Si se utiliza este tipo de código:

Point P;
P = anotherP;

se llama el operador de asignación.

Espero que ayude.

Cuando "paso por valor", tal como se encuentra en su definición de operador =, se hace una copia del tipo para su uso como un valor local al método. Su operador no está siendo llamado debido a que el sistema no puede encontrar un contructor que toma vector3 -. Que haya definido un constructor de copia que se lleva a vector3 y

Por lo tanto, como otros han dicho, lo que quiere hacer es definir su operador = como tomar

const vector3& p

También deberá actualizar el constructor de copia declarada tomar vector3 const también.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top