当前位置: 动力学知识库 > 问答 > 编程问答 >

C++ Calling a non-const operator overload with two const arguments

问题描述:

I've overloaded the operator- (and -=) for 2D vectors (and scalars):

Vector2D Vector2D::operator-(const Vector2D& rhs) {

return Vector2D(this->GetX() - rhs.GetX(), this->GetY() - rhs.GetY());

}

In order to get this call to not complain that no operator '-' matches these arguments I had to do this:

a2de::Vector2D Vector2D::GetFacingVector(const Vector2D& target, const Vector2D& source) {

a2de::Vector2D facingVec(const_cast<Vector2D&>(target) - const_cast<Vector2D&>(source));

return facingVec;

}

Or this:

a2de::Vector2D Vector2D::GetFacingVector(const Vector2D& target, const Vector2D& source) {

a2de::Vector2D facingVec(Vector2D(target) - Vector2D(source));

return facingVec;

}

Both of which seem like a very bad thing to do. (Not-with-standing the phrase "only use const_cast when you know what you're doing because the compiler will assume you do!")

Are these correct or is there a better way to accomplish the same thing?

网友答案:

Your operator should be:

Vector2D Vector2D::operator-(const Vector2D& rhs) const

Note the const.

网友答案:

Your operator- should be declared as a const member function, meaning it promises not to change *this:

Vector2D Vector2D::operator-(const Vector2D& rhs) const {
    return Vector2D(this->GetX() - rhs.GetX(), this->GetY() - rhs.GetY());
}

Or better still, make it a non-member, so that implicit conversions can happen on both sides of a minus sign, not just the right side:

inline Vector2D operator-(const Vector2D& lhs, const Vector2D& rhs) {
    Vector2D result(lhs);
    result -= rhs;
    return result;
}
网友答案:

There are lots of ways to use const. Here are some that may fix your problem

Vector2D Vector2D::operator-(const Vector2D& rhs) const
{
    return Vector2D(this->GetX() - rhs.GetX(), this->GetY() - rhs.GetY());
}

Notice the const at the end of your method? This signifies that the method is guaranteed not to change any member variable during it's scope.

网友答案:

Try mark operator- as const member function.

网友答案:

I'd better try to not write the words that spring to mind. Suffice it to say, they would cause extreme downvoting of this answer, and maybe even drag in the Reddit crowd. Anyways, your member function is not const, so it must be called on non-const argument.

Here's direct technical fix:

Vector2D Vector2D::operator-(const Vector2D& rhs) const
{
    return Vector2D(this->GetX() - rhs.GetX(), this->GetY() - rhs.GetY());
}

Here's a better way, with the operator as a free-standing function:

Vector2D operator-( Vector2D const& a, Vector2D const& b)
{
    return Vector2D( a.GetX() - b.GetX(), a.GetY() - b.GetY() );
}

Finally, think about naming. Do you ever write getSin( angle )? No?

Vector2D operator-( Vector2D const& a, Vector2D const& b)
{
    return Vector2D( a.x() - b.x(), a.y() - b.y() );
}
网友答案:

Another possibility is to make operator a nonmember function. This way you don't run into your problem. Also, both arguments could be converted to Vector2D if you have constructors to do that.

class Vector2D
{
...
    Vector2D& operator-=(const Vector2D& rhs)
    {
      this->x -= rhs.GetX();
      this->y -= rhs.GetY();
      return *this;
    }
...
};

Vector2D Vector2D::operator-(const Vector2D& lhs, const Vector2D& rhs)
{
  Vector2D temp(lhs);
  return temp -= rhs;
}

Most non-modifying arithmetic operators in the standard are non-member symmetric like this.

分享给朋友:
您可能感兴趣的文章:
随机阅读: