Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assignment operator overloading: returning void versus returning reference parameter [duplicate]

Some of the assignment overloading operator examples I see online look like this:

#include <iostream>
using namespace std;

class Distance {
   private:
      int feet;             // 0 to infinite
      int inches;           // 0 to 12
   public:
      // required constructors
      Distance(){
         feet = 0;
         inches = 0;
      }

      Distance(int f, int i){
         feet = f;
         inches = i;
      }

      void operator = (const Distance &D ) { 
         cout << "assigning..." << endl;
         feet = D.feet;
         inches = D.inches;
      }

      // method to display distance
      void displayDistance() {
         cout << "F: " << feet <<  " I:" <<  inches << endl;
      }

};

int main() {
   Distance D1(11, 10), D2(5, 11);

   cout << "First Distance : "; 
   D1.displayDistance();
   cout << "Second Distance :"; 
   D2.displayDistance();

   // use assignment operator
   D1 = D2;
   cout << "First Distance :"; 
   D1.displayDistance();

   return 0;
}

They return void from the overloaded function. This makes sense to me if D1 is the object being called.

Other examples return a reference to a class object.

#include <iostream>
using namespace std;

class Distance {
   private:
      int feet;             // 0 to infinite
      int inches;           // 0 to 12
   public:
      // required constructors
      Distance(){
         feet = 0;
         inches = 0;
      }

      Distance(int f, int i){
         feet = f;
         inches = i;
      }

      Distance& operator = (const Distance &D ) { 
         cout << "assigning..." << endl;
         feet = D.feet;
         inches = D.inches;
         return *this;
      }

      // method to display distance
      void displayDistance() {
         cout << "F: " << feet <<  " I:" <<  inches << endl;
      }

};

int main() {
   Distance D1(11, 10), D2(5, 11);

   cout << "First Distance : "; 
   D1.displayDistance();
   cout << "Second Distance :"; 
   D2.displayDistance();

   // use assignment operator
   D1 = D2;
   cout << "First Distance :"; 
   D1.displayDistance();

   return 0;
}

This does not make sense to me (when taking the first example into consideration). If in the first example D1 = D2; invokes something like D1.=(D2);, why would the second example work in that case? Is it something like D1 = D1.=(D2);? And does it make any difference at the end of the day?

like image 325
JoeBass Avatar asked Feb 20 '17 01:02

JoeBass


1 Answers

Although C++ language lets you overload assignment operator with any return type, including void, you should strongly consider following a widespread convention of returning a reference to the assignee from the operator.

The rationale for it is that

A = B;

will work no matter what the assignment returns, while

A = B = C;

which is a perfect chain of assignments will break, unless B = C returns something assignment-compatible to A (which is usually an object of the same type as A).

Another problem is in situations when you must compare the object as part of a larger expression, for example

mytype obj;
while ((obj = read_obj(cin)) != END_OBJ) {
    ...
}

Hence, the biggest drawback to returning void is inability to chain assignments and use them in places where void is not allowed.

like image 174
Sergey Kalinichenko Avatar answered Oct 20 '22 13:10

Sergey Kalinichenko