简体   繁体   中英

call by reference, overloading operators, inline and const

for some vector arithmetics in 3 dimensions I defined a vector class with consturctors and I try to overload some operators:

class Vector3{
public:

typedef double d_type;
d_type x,y,z;
Vector3(d_type d_x, d_type d_y, d_type d_z){x = d_x; y = d_y; z = d_z;}
Vector3(){x=0;y=0;z=0;}

Vector3 operator +( Vector3 &v){return Vector3(this->x + v.x, this->y + v.y, this->z + v.z);}
Vector3 operator -( Vector3 &v){return Vector3(this->x - v.x, this->y - v.y, this->z - v.z);}


Vector3 operator +=( Vector3 &v){return Vector3(this->x += v.x, this->y += v.y, this->z += v.z);}
Vector3 operator -=( Vector3 &v){return Vector3(this->x -= v.x, this->y -= v.y, this->z -= v.z);}

};

if I understand it right, "&v" is a call by reference, only a reference is put on the stack, not the whole object Vector3 v. Is *v also possible as a call by reference? I have seen some other versions like:

      inline Vector3 operator+(const Vector3& u, const Vector3& v)  
       {return Vector3(u.x + v.x, u.y + v.y,u.z + v.z);}
      inline Vector3 operator-(const Vector3& v)    
       {return Vector3(-v.x, -v.y, -v.z);}

      const Vector3& operator+=(const Vector3& v)  {x+=v.x;y+=v.y;z+=v.z;return *this;}
      const Vector3& operator-=(const Vector3& v)  {x-=v.x;y-=v.y;z-=v.z;return *this;}

Why use "inline" and "const"? does it give a runtime boost? Is there a difference between "Vector3& v" and "Vector3 &v"? What are the advantages and disadvanteages of overloading the operators in that kind of way?

First, the idea of "pass by reference" is slightly muddled in c++ because there are pointers and references, and both allow the idea, but due to naming it can be misconstrued, and misunderstandings can happen when people communicate. But you can "pass by reference" without using "references", insofar as you are not passing a copy of the object, and changes through the argument can affect the caller's object.

A member declared like this:

Vector3 operator +( Vector3 &v);

Indeed takes an lvalue reference to v, so no copy is made. However, in C++, a function that takes a non-const reference to a parameter is advertising, "I plan to possibly change this object." If that's not the case, then you should change the signature to this:

Vector3 operator + (Vector3 const& v);

Also, if you have rvalues, they can bind to references-to-const object, but cannot bind to references-to-nonconst objects. The idea is, mutating a temporary object is usually a mistake, so the language doesn't let you. (And if you really want to do that, you cause take an rvalue-reference.

As for inline, that is only necessary if you plan to define the function in a header, and it is defined outside the class body. The keyword is less about performance, and more about how the object code is generated, so that the linker won't complain if it sees multiple copies of the function. (If a.cpp, b.cpp, and c.cpp each include your header that defines a function, you end up with a copy of the function in each translation unit, and if they weren't "inline", their "linkage" would require a single definition, and the linker would see multiple and complain about multiply defined function. With inline, the linker does not complain, but merely picks an implementation (since they're all the same) and uses it.

As for your return value question, this is not a good signature to use:

Vector3 operator +=( Vector3 &v);

It should be:

Vector3& operator +=( Vector3 const& v);

Const is described above, and the return value being a reference allows no temporary object construction for the return value, and also you can "chain" calls together. Since operator+= modifies the object it's called on, the normal return value for this function is to return *this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM