es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo funciona el constructor de copia que devuelve un valor y descarta la temporal?

Al tener este código:

#include <iostream>

class Base {
public:
    Base() = default;

    explicit Base(int val) : _var(val) {}

    Base operator=(const Base &rhs) {
        _var = rhs._var;
        return *this;
    }

    void print() const {
        std::cout << _var << std::endl;
    }

private:
    int _var;
};

int main() {
    Base b[] = {Base(10), Base(), Base(), Base()};
    (b[1] = b[2]) = b[0];
    for (Base base: b) {
        base.print();
    }
}

La salida es:

10
0
0
0

Pero esperaría:

10
10
0
0

Ya que el segundo elemento en el arreglo b[1] debería recibir asignación de b[0], pero el operador de asignación devuelve un valor, no una referencia, lo que causa una construcción por copia. Aún así, ¿por qué no se construye por copia b[1] para tener _var=10?

Si el operator= devolviera Base &, la salida sería la esperada.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Como se menciona en la pregunta, el problema es que la función operator= devuelve un objeto Base en lugar de una referencia a Base. Esto provoca la construcción de copias de objetos Base en lugar de modificarlos en su lugar.

    En el código dado, la sentencia (b[1] = b[2]) = b[0] primero asigna b[2] a b[1] usando la función operator=. Como ésta devuelve un objeto Base, b[1] se construye mediante copia con el valor de b[2]. Luego, se asigna b[0] a este nuevo objeto usando la misma función operator=, lo que provoca de nuevo la construcción de una copia de b[0].

    Si la función operator= se hubiera definido para devolver una referencia a Base en lugar de un objeto Base, entonces las asignaciones en la sentencia (b[1] = b[2]) = b[0] modificarían los objetos Base existentes en su lugar y producirían el resultado esperado:

    10
    10
    0
    0
    

Comments are closed.