Overloading the operator =


I'm performing the operator overload = for a Rational data type. That is, for this to work with the Rational type:

res = p;

According to the book I am following, it tells me to do it with the operator = as a member function (method) and:

  • That you receive a type by reference.
  • That I create an object with the copy constructor passing it as a parameter the object received in said function.
  • To exchange that object created by the * this.
  • That returns this.

    Implementing it, and working there are no problems (it works perfectly) with the version I've made, which would be this (correct me if it's not right):

    Racional& Racional::operator=(const Racional& der)
      Racional auxiliar(der);
      this->numerador = auxiliar.obtenerNumerador();
      this->denominador = auxiliar.obtenerDenominador();
      return *this;

    My doubt is as follows. Why do I have to create an auxiliary object if I can directly do it:

    Racional& Racional::operator=(const Racional& der)
      this->numerador = der.obtenerNumerador();
      this->denominador = der.obtenerDenominador();
      return *this;

    Thank you very much for all your colleagues.

    asked by ProgrammerJr 09.02.2018 в 11:51

    1 answer


    Why do I have to create an auxiliary object?

    In my opinion the question should be " Why should I adopt a concrete solution in this particular case? ".

    In the assignment operator (and its malign twin, the motion operator) there is not a single valid solution or pattern always, each type of data may require a different solution.

    The copy-exchange idiom.

    As you have said, in the specific case of your type Racional you do not need any auxiliary object. It is possible that the auxiliary is mentioned as part of the copy-exchange idiom ( copy swap idiom in English).

    The copy-exchange idiom consists of delegating the functionality of assigning new values in the copy constructor, by creating a local copy of the data that will then be exchanged with the current data; then the temporary object (which contains the old data) is destroyed. It is precisely the idiom that you have used Trauma in your answer :

    Racional& Racional::operator=( const Racional &der ) {
        Racional tmp( der );     // Copiamos el Racional recibido.
        std::swap( *this, tmp ); // Intercambiamos con el Racional presente.
        return *this; // Devolvemos el Racional presente, por si queremos encadenar operaciones.
    } // El auxiliar se destruye.

    Is the auxiliary necessary?

    The copy-exchange idiom uses an auxiliary to ensure that the destructor of the object is called for the data that is being discarded; this is relevant in cases where the object manages resources:

    struct Int {
        int *i{nullptr};
        Int(const Int &) = default;
        ~Int() {
            delete i;
        Int &operator =(const Int &i) {
            Int tmp(i);
            std::swap(*this, tmp);
            return *this; // delete i sera llamado.

    If in the previous example the assignment operator had been this:

    Int &operator =(const Int &i) {
        this->i = i;

    We would lose the pointer% original%, causing a memory leak. But it's not your case, your class i does not handle resources so you do not need to use the copy-exchange idiom.


    C ++ allows overloading operators so that we can take care of special tasks that an object may require when being operated; This customization of behavior is special in each case and although there are certain idioms we should not use them without thinking if the specific needs of each case are adjusted.

    In your case, your doubt is relevant and correct; the answer is: you do not need the temporary ... but DO NOT consider this response recorded in stone, in other situations the answer could be different.

    answered by 09.02.2018 / 12:38