如何在不修改操作数的情况下使用运算符重载链?

时间:2012-04-28 03:07:29

标签: c++ memory overloading memory-leaks operator-keyword

假设我们有这个A类:

class A
{
public:
   int a;

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

我想创建一个+重载,以便我可以像这样使用它

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

不修改每个对象的内容。下一个合乎逻辑的事情是每次都分配一块新的内存:

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

但这会产生一个新问题:中间结果丢失,导致内存泄漏。 我可以通过制作一个静态函数来轻松解决这个问题,该函数需要三个A对象引用并将前两个的总和存储在第三个中,但我愿意打赌必须有一些方法来使+重载发生的方式我想要。

所以问题是:有没有办法可以使用一系列操作符重载,这些重载不会在不导致内存泄漏的情况下修改操作数?

2 个答案:

答案 0 :(得分:10)

您只需使用按值传递即可:

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

或者,由于成员a可公开访问,因此您可以(而不是 )使operator+成为非成员函数:

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

请注意,第一个参数是按值接受,第二个是按引用。这样,您就不需要在函数中声明局部变量。你可以使用第一个参数;毕竟它是函数的本地函数,你可以做任何你想做的事情:在这种情况下,我们只需要添加right.a,然后返回它。


更好的课程设计是:(阅读评论)

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;
}

答案 1 :(得分:4)

无需在operator+内使用指针。您可以在堆栈中分配中间对象,然后将其返回:

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

或者只是:

A operator+ (const A &b)
{
   return A(a+b.a);
}

甚至更简单:

A operator+ (const A &b)
{
   return a+b.a;
}

因为这会隐式调用A::A(int)

请注意,我从返回类型中删除了引用。您不能将非const引用返回给本地。

然后你会这样使用它:

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

请注意,d不再是参考。