2

我正在为向量和矩阵编写一个类,我想了解当我想重载 +、-、* 和 / 等常见运算符时如何避免开销和泄漏。

例如:

int main()
{
    Vector3 aVector; //This has an address #1
    Vector3 bVector; //This has another address #2

    //rVector has an address #3
    Vector3 rVector = aVector - bVector; //What will happen here?
}

和向量类:

class Vector3
{
    public:
        float vX, vY, vZ;
        Vector3& operator-(const Vector3& vector3)
        {
            //I want to calculate this vector with the "vector3" param
            //But then what do I return?

            //Test 1:
            Vector3 result; //This has an address #4
            result.vX = vX - vector3.vX;
            result.vY = vY - vector3.vY;
            result.vZ = vZ - vector3.vZ;

            return result; //Did I just overwrite address #3?

            //Test 2:
            vX = vX - vector3.vX;
            vY = vY - vector3.vY;
            vZ = vZ - vector3.vZ;

            return (*this); //What happened to address #3? And I just changed this vector's values and I need then again later
        }
}

最好的方法是什么?

编辑:还有一个问题,如果我想这样做:

Vector3 myVector = someVector - Vector3(x, y, z);

我如何对构造函数进行编码,使其不做任何事情……不好?我在想它会创建一个新类,但是在上面的句子中使用它之后我将无法引用它,这会导致以后出现问题吗?

4

3 回答 3

1

您的实现没有任何泄漏。当超出函数范围时,您创建的每个向量都会被破坏。

至于返回值,我建议你按值返回(去掉&)。

对于你的第二个问题:它不是新的,所以没有泄漏。此外,您不需要引用它,因此没有真正的问题。

于 2013-08-16T20:02:20.407 回答
0

创建operator-为命名空间范围函数(而不是成员函数):

Vector3 operator-(const Vector3 &lhs, const Vector3 &rhs)
{
  Vector3 result{lhs};

  // Subtract out rhs
  ...

  // Do the math
  return result;
}

在任何情况下都不会泄露任何东西,因为您没有从堆(空闲存储)中分配任何东西。

于 2013-08-16T20:01:41.337 回答
0

测试 1 会将答案存储在一个新向量(结果)中,并假设将其作为对 rVector 的引用返回。

rVector = result

aVector = //its original value

测试 2 会将答案存储在调用函数的向量 (aVector) 中,并将其作为对 rVector 的引用返回。

rVector = aVector

aVector = //the answer

尽管使用测试 2 会节省内存,但答案存储在函数之外的两个位置(rVector 和 aVector),这可能不是您想要的。测试 1 是更安全的选项,但请确保按值返回它以避免超出范围的错误,正如此处其他人指出的那样。

于 2013-08-16T20:17:15.323 回答