3

我有一个对象,其运算符定义如下:

P& operator +(const P &rhs) {
    return P(x + rhs.x, y + rhs.y, z + rhs.z);
}

它没有自定义复制或赋值运算符。

在我直接分配向量内的加法结果后,其中会出现垃圾。

P p1(1.0, 0.0, 0.0);
P p2(0.0, 0.0, 0.0);

vector<P> v(1);
v[0] = p1 + p2; // v[0] now contains garbage.

如果我通过一个变量来做,一切都如预期的那样。

vector<P> u(1);
P q = p1 + p2;
u[0] = q; // u[0] contains correct value.

这种行为的原因是什么?这两种情况有什么区别?

4

2 回答 2

10

您返回对临时的引用。这是一个坏主意,因为临时变量在函数末尾超出范围(在本例中为operator+函数)。将您的运营商声明为:

P operator +(const P &rhs) const

反而。

于 2012-05-02T17:12:05.267 回答
3

如你所见

P& operator +(const P &rhs) 
{
    return P(x + rhs.x, y + rhs.y, z + rhs.z);
}

返回对局部变量的引用,一旦超出函数范围,该变量就会被销毁operator +

您可以将指针返回到堆中创建的数据,但如果调用者未能删除对象,这将为内存泄漏留下足够的空间。

您也可以将对象作为副本返回,但这有时可能是一个真正的开销

在最近的 C++11 中,使用 move 构造来转移所有权,这应该是未来理想和首选的方法。

于 2012-05-02T17:15:08.063 回答