1

我已经为 2D 向量(和标量)重载了operator-(and -=):

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

为了让这个电话不抱怨no operator '-' matches these arguments我必须这样做:

a2de::Vector2D Vector2D::GetFacingVector(const Vector2D& target, const Vector2D& source) {
    a2de::Vector2D facingVec(const_cast<Vector2D&>(target) - const_cast<Vector2D&>(source));
    return facingVec;
}

或这个:

a2de::Vector2D Vector2D::GetFacingVector(const Vector2D& target, const Vector2D& source) {
    a2de::Vector2D facingVec(Vector2D(target) - Vector2D(source));
    return facingVec;
}

这两件事似乎都是一件非常糟糕的事情。(不支持短语“仅const_cast在您知道自己在做什么时使用,因为编译器会假设您这样做!”)

这些是正确的还是有更好的方法来完成同样的事情?

4

6 回答 6

2

您的运营商应该是:

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

注意const

于 2012-08-10T02:21:14.090 回答
2

operator-应该被声明为一个const成员函数,这意味着它承诺不会改变*this

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

或者更好的是,使其成为非成员,以便隐式转换可以发生在减号的两侧,而不仅仅是右侧:

inline Vector2D operator-(const Vector2D& lhs, const Vector2D& rhs) {
    Vector2D result(lhs);
    result -= rhs;
    return result;
}
于 2012-08-10T02:21:40.410 回答
2

有很多使用方法const。这里有一些可能会解决您的问题

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

注意const方法末尾的 ?这意味着该方法保证在其作用域内不会更改任何成员变量

于 2012-08-10T02:22:26.493 回答
1

尝试将 operator- 标记为 const 成员函数。

于 2012-08-10T02:20:13.203 回答
1

我最好尽量不写那些浮现在脑海中的词。可以这么说,他们会导致对这个答案的极度反对,甚至可能会拖累 Reddit 人群。无论如何,您的成员函数不是const,因此必须在非const参数上调用它。

这是直接的技术修复:

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

这是一种更好的方法,将运算符作为独立函数:

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

最后,考虑命名。你写过getSin( angle )吗?不?

Vector2D operator-( Vector2D const& a, Vector2D const& b)
{
    return Vector2D( a.x() - b.x(), a.y() - b.y() );
}
于 2012-08-10T02:22:28.790 回答
0

另一种可能性是使运算符成为非成员函数。这样你就不会遇到问题。此外,如果您有构造函数来执行此操作,则两个参数都可以转换为 Vector2D。

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

标准中的大多数非修改算术运算符都是这样的非成员对称的。

于 2012-08-10T02:41:12.680 回答