如何在不修改操作数的情况下使用操作符重载链? [英] How do I use a chain of operator overloads without modifying the operands?

查看:76
本文介绍了如何在不修改操作数的情况下使用操作符重载链?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

问题是:有什么方法可以使用操作符重载链而不会在不引起内存泄漏的情况下修改操作数?

解决方案

您可以简单地使用按值传递并执行以下操作:

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

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?

解决方案

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

这篇关于如何在不修改操作数的情况下使用操作符重载链?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆