I’m writing a C++ vector class for a project and I’m having a hard time making a decision about how best to write some of the methods. Before I start I will say that the class has a good copy constructor and assignment operator (this will be relevant in a sec). The class has a set of static methods that return vectors when I want to make sure that neither parameter is altered, they have signatures like:
Vector* Vector::subtract(const Vector* v, const Vector* u)
{
double outX = v->myX - u->myX;
double outY = v->myY - u->myY;
double outZ = v->myZ - u->myZ;
return new Vector(outX, outY, outZ);
}
The problem I am having is that I don’t want to return pointers if I can help it. So instead I did some testing and realized that if I just say
return Vector(outX, outY, outZ)
and then assign the result like
Vector foo = Vector::subtract(bar, temp)
it will create a copy and work fine. Here’s where my question lies: I just called the constructor twice (essentially) is there a way to get around that? Secondly, if I use this method as a argument to another method like
foo.multiply(&Vector::subtract(foo, bar), 5)
will it still create a copy or did I just pass the pointer that has gone out of scope in the Vector::subtract method?
More generally, what is the best (or at least is there a better) way to do this?
Have you ever heard of Return Value Optimization? There is nothing you have to do. The compiler will most likely eliminate the copy for you. Now, if you use C++11 and the
Vectorclass manages a resource, you could declare a move constructor also, so that the returned value is moved just in case the compiler decides it cannot perform RVO. However, it looks like the class only holds 3 values, if that is the case, copying is going to be as efficient as moving.What is the
&for? Was that a mistake? Also, the member function is not declaredstaticso the syntax is wrong. Anyways, assumingsubtractreturns a copy, it will return a copy and pass that to themultiplyfunction as an argument.Also, on another note,
Vector* Vector::subtract(const Vector* v, const Vector* u)
would be better asVector* Vector::subtract(const Vector& v, const Vector& u), this makes the syntax cleaner when you pass arguments to subtract, etc.So changing your code, it would look something like the following: