假设我们有这个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对象引用并将前两个的总和存储在第三个中,但我愿意打赌必须有一些方法来使+重载发生的方式我想要。
所以问题是:有没有办法可以使用一系列操作符重载,这些重载不会在不导致内存泄漏的情况下修改操作数?
答案 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
不再是参考。