0

From the examples I have seen when people use the operator+ when adding two instances of a class, the usual pattern is to return an object. Suppose we have a Vector class with attributes u and v, an implementation of operator+ could be,

Vector2 Vector2::operator+(const Vector2& other) {
    return Vector2(this->u + other.u, this->v + other.v);
}

Why is the standard pattern not to return a reference? This is returning an object that was created on the Stack, this means that it should be garbage collected later on when we leave the function and could lead to problems from what previously pointed to it. e.g.

Vector2 v = Vector(10,20) + Vector(30, 40), would v later be pointing to a garbage collected variable? Because the result of Vector(10, 20) + Vector(30, 40) was created on a Stack (That we have now left).

What I am saying is, why should this not be something like,

Vector2* Vector2::operator+(const Vector2& other) {
    return new Vector2(this->u + other.u, this->v + other.v);
}
Joe Smith
  • 107
  • 5
  • 1
    `would v later be pointing to a garbage collected variable?` No. – tkausl Dec 08 '21 at 00:36
  • An expression `a + b` returns an object distinct from both `a` and `b`. The only inputs to it are (references to) `a` and `b`, and it's not possible to return a reference to either. Returning a reference to an object created locally within the `operator+()` function gives undefined behaviour, since the local ceases to exist on return to the caller. Returning a reference to a dynamically allocated object (e.g. created with a `new` expression) causes a memory leak - since the code that calculates `a + b` does not normally expect to need to explicitly `delete` that returned object. – Peter Dec 08 '21 at 00:41

1 Answers1

1

Should you return a reference using operator+ for adding two classes together?

No.

Why is the standard pattern not to return a reference?

Because the binary + operator conventionally returns a new object.

Vector2 v = Vector(10,20) + Vector(30, 40), would v later be pointing to a garbage collected variable?

No. C++ has no garbage collector, and Vector2 is presumably not a pointer.

What I am saying is, why should this not be something like,

Vector2* Vector2::operator+(const Vector2& other) {
    return new Vector2(this->u + other.u, this->v + other.v);
}

Because:

  1. Using bare owning pointers is a horrible idea.
  2. Returning bare owning pointer makes the idea even worse.
  3. Operator overloads that represent the abstract operation as the fundamental operation (for example, addition in this case) should conform to the same interface and behaviour as the fundamental operation.
    • The type of 1 + 1 is not int*, and so the type of vector + vector shouldn't be Vector2*.
    • There is no need to delete the result of 1 + 1 and so there shouldn't be a need to delete the result of vector + vector.
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • I have ran into situations where I have created an object inside a function, returned that object and because it was created into a Stack, it was later destroyed when we left the function call. Why does this not apply here? – Joe Smith Dec 08 '21 at 01:47
  • 1
    @JoeSmith Automatic variables are supposed to be destroyed when you leave a scope. This is intentional and desirable. – eerorika Dec 08 '21 at 01:53
  • Why does automatic variables not apply here? Sorry I am still 50/50, I thought of the behaviour of your sentence "are supposed to be destroyed when you leave a scope.", I thought the Vector2 returned in the function would be destroyed. – Joe Smith Dec 08 '21 at 21:50
  • @JoeSmith What do you mean by automatic variables not applying here? Yes, the Vector2 will eventually be destroyed, when the lifetime of the object that it initialises ends. – eerorika Dec 08 '21 at 21:54
  • It's just that you said "supposed to be destroyed when you leave a scope", when we left the function scope that created the Vector2 (The operator+ function) why would that newly created object not be destroyed, leading to the result of Vector2(10, 10) + Vector2(20, 20) returning a destroyed object? It's like in some examples variables created in a function will be automatically cleaned when we left, and some do not. – Joe Smith Dec 08 '21 at 22:00