Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use a chain of operator overloads without modifying the operands?

Let's say we have this class A:

class A
{
public:
   int a;

   A(int b)
   {
      a = b;
   }
};

I would like to create a + overload such that I could use it like this

A a(1),b(2),c(3),&d;
d = a + b + c;

without modifying the content of each object. The next logical thing would be allocating a new chunk of memory each time like this:

A &operator+ (const A &b)
{
   A *c = new A(a+b.a);
   return *c;
}

But this would create a new problem: intermediate results are lost, causing memory leaks. I could have easily solved this problem by making a static function that takes three A object references and stores the sum of the first two in the third, but I'm willing to bet that there must be some way to make + overload happen the way I want.

So the question is: is there any way I could use a chain of operator overloads that do not modify the operands without causing memory leaks?

like image 512
Kang Min Yoo Avatar asked Apr 28 '12 03:04

Kang Min Yoo


People also ask

Can we overload only existing operator?

We can only overload the existing operators, Can't overload new operators. Some operators cannot be overloaded using a friend function. However, such operators can be overloaded using the member function.

Can you overload an overloaded operator?

You can redefine or overload the function of most built-in operators in C++. These operators can be overloaded globally or on a class-by-class basis. Overloaded operators are implemented as functions and can be member functions or global functions. An overloaded operator is called an operator function.


1 Answers

You can simply use pass by value and do this:

A operator+ (A other) //pass by value
{
   other.a += a;
   return other;
}

Or, since the member a is publicly accessible, you can (rather should) make operator+ a non-member function as:

A operator+(A left, A const &right) 
{
   left.a += right.a;
   return left;
}

Notice that the first argument is accepted by value, and second by reference. In this way, you don't need to declare a local variable in the function. You can use the first parameter; after all it is local to the function, you can do whatever you want to do with it: in this case, we just add right.a to it, and return it.


A better design of class would be this: (read the comments)

class A
{
   int a;  //make it private
public:    
   A(int b) : a(b) //use member initialization list
   {
   }
   A& operator+=(A const & other)  //add `+=` overload, as member of the class
   {
      a += other.a;
      return *this;
   }
};

//and make `+` non-member and non-friend 
A operator+(A left, A const & right) 
{
  left += right; //compute this in terms of `+=` which is a member function
  return left;
}
like image 61
Nawaz Avatar answered Sep 28 '22 08:09

Nawaz