6

假设我们有这个 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 对象引用并将前两个的总和存储在第三个中,但我敢打赌,一定有某种方法可以使 + 重载以这种方式发生我想。

所以问题是:有什么方法可以使用一系列运算符重载,不会修改操作数而不会导致内存泄漏?

4

2 回答 2

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;
}
于 2012-04-28T03:15:30.790 回答
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;
}

由于 this 隐式调用A::A(int).

请注意,我从返回类型中删除了引用。您不能返回对本地的非常量引用。

然后你会这样使用它:

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

请注意,d不再是参考。

于 2012-04-28T03:11:14.020 回答