2

I'm coding a class for Vector and Matrices and I'd like to understand how can I avoid overheads and leaks when I want to overload common operators such as +, -, * and /.

For example:

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

And the vector class:

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

What's the best way to do this?

edit: One more question, if I want to do this:

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

How do I code the constructor so it doesn't do anything... bad? I'm thinking it'll be creating a new class but I won't have any means to reference it after it's used in the sentence above, can this lead to problems later?

Danicco
  • 1,573
  • 2
  • 23
  • 49
  • 3
    `operator-` should return by value. It makes no sense to return a reference here. – juanchopanza Aug 16 '13 at 20:00
  • Just to expand @juanchopanza, returning the reference here is returning a reference to an out of scope object. Its like returning a pointer to an out of scope object: you're gonna break something. Return by value here. The return should either be elided, so don't wory (too much) about spurious copies. If you are *really* worried, you can make move constructors and assignments and you're done! – IdeaHat Aug 16 '13 at 20:05
  • Generally, `operator+` and `operator-` return by value. However, `operator+=` and `operator-=` often return by reference. – Xaqq Aug 16 '13 at 20:06
  • With performance in mind, since I'll be doing this operation as many times per second as I can, is this still the best solution? Returning by value wouldn't re-create the vector class again when I could just return an existing one? – Danicco Aug 16 '13 at 20:12
  • @Danicco Naw, C++ compilers are pretty smart, look up return elision. – IdeaHat Aug 16 '13 at 20:24
  • @MadScienceDreams not only that, but semantically it would be weird for `A + B` to return a reference to either `A` or `B`. – juanchopanza Aug 16 '13 at 21:18

3 Answers3

1

Your implementation doesn't have any leaks. Every vector you create is destructed when getting out of the scope of the function.

As for the return value, I suggest you return it by value (just remove the &).

For your second question: It's not a new so there is no leak. Also, you don't need to reference it so there is no real issue.

MasterPlanMan
  • 992
  • 7
  • 14
  • 1
    It doesn't have any "leaks", but returning a reference to an out-of-scope object is certainly an error. – IdeaHat Aug 16 '13 at 20:03
  • It's not a leak - it's misusing the & operator. And there's no issue (no crash - doesn't mean it's a good idea though) until you use it after its destruction. – MasterPlanMan Aug 16 '13 at 20:05
  • Also, if it's a const reference, the life of the object may be extended as seen here http://stackoverflow.com/questions/2615162/return-value-not-a-reference-from-the-function-bound-to-a-const-reference-in – MasterPlanMan Aug 16 '13 at 20:07
0

Create operator- as a namespace scope function (not as a member function):

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

  // Subtract out rhs
  ...

  // Do the math
  return result;
}

Nothing gets leaked in any case, because you haven't allocated anything off of the heap (free store).

Michael Goldshteyn
  • 71,784
  • 24
  • 131
  • 181
0

Test 1 will store the answer in a new vector (result) and hypothetically return it as a reference to rVector.

rVector = result

aVector = //its original value

Test 2 will store the answer in the vector the function was called on (aVector) and returns that as a reference to rVector.

rVector = aVector

aVector = //the answer

Although using test 2 will save memory the answer is stored in two places outside the function (rVector and aVector) which may not be what you want. Test 1 is the safer option but make sure to return it by value to avoid out-of-scope errors as others here have pointed out.

Dolchio
  • 469
  • 2
  • 12