【问题标题】:C++ Vector Operator OverloadingC++ 向量运算符重载
【发布时间】:2013-11-10 22:09:32
【问题描述】:

我试图找到一个简单的示例程序,它重载了数学向量的以下运算符。

Constructor  // create

= (equals)     // assign

+; -; +=; -=   // add sub

*; /; *=; /=   // multi divide

++; -- // plus minus

==    // compare
>; >=
<; <=

[]    // access a value

似乎找不到任何好的简单教程。我强调简单,因为我现在才学习这些东西。如果有人可以链接我,或者甚至更好地为一个运算符编写一个简单的重载作为示例,那将是不可思议的!

【问题讨论】:

  • 当你说“数学向量”时,它的实际类型是什么?
  • 在大学的未来工作中,我被告知我们将使用“数学向量,而不是 STL 向量”,所以不确定它们是相同的还是不同的。
  • 另外,如果我必须创建一个“向量类对象”,那是什么意思?是继承自vector的类吗?
  • 我认为“数学”向量是指坐标向量,而不是对象数组。

标签: c++ vector operator-overloading overloading


【解决方案1】:

在编写运算符时需要了解一些事项,这些事项不常与其他函数一起使用。

例如,赋值运算符将return *this,因为您更改了向量的值:

class v {
public:
  double x_, y_;
  v& operator += (const v& rhs)
  {
     _x += rhs._x;
     _y += rhs._y;
     return *this;
  }
};

另一个有趣的是,前++ 和后++ 不同只是因为一个未使用的参数:

class v {
public:
  double x_, y_;
  v& operator ++ (); // ++v
  v& operator ++ (int); // v++
};

“等于”(赋值)是另一个在使用指针时比较棘手的问题。对于一个向量,一般不会有问题,但是如果你定义一个向量V并赋值给它自己,你就要小心了:

class v {
public:
  double x_, y_;
  v& operator = (const v& rhs)
  {
    if(this != &rhs)
    {
      x_ = rhs.x_;
      y_ = rhs.y_;
    }
    return *this;
  }
};

在你的情况下,if() 肯定不会有用,但考虑做这样的事情:

   delete p_;
   p_ = new foo;
   p_->x_ = rhs.p_->x_;

如果&amp;rhs == this,那么delete p_ 删除了rhs 指针!这意味着在第 3 行访问它是一个错误。

其余的应该很容易使用。比较运算符返回bool 并且是const

class v {
public:
  double x_, y_;
  bool operator == (const v& rhs) const
  {
    return x_ == rhs.x_ && y_ == rhs.y_;
  }
};

虽然,从 C++20 开始,您应该只声​​明三路比较运算符 &lt;=&gt;,它允许编译器为您实现所有其他比较运算符。这个返回一个负数(较小:a b)。

我不确定是什么让向量变大或变小,我在这个例子中使用了从 (0, 0) 开始的长度:

class v {
public:
  double x_, y_;
  int operator <=> (const v& rhs) const
  {
    if(x_ == rhs.x_ && y_ == rhs.y_)
    {
      return 0;
    }
    return length() > rhs.length() ? 1 : -1;
  }
};

[] 运算符除外。该版本有两个版本:

class v {
public:
  // I would imagine you'd use an array but as a simple example...
  double x_, y_;
  double operator [] (int idx) const
  {
    return idx == 0 ? x_ : y_;
  }
  v_ref operator [] (int idx)
  {
    v_ref v(this, idx);
    return v;
  }
};

如您所见,非常量版本的 [] 运算符返回一个引用。这是必要的,因此您可以编写如下内容:

r[3] = 7.3;

r[3] 返回该引用,然后以7.3 作为参数调用引用的赋值。 (请注意,如果您使用 3 作为索引,而您只有 2 个值:0 和 1,我们可能会抛出错误:此处未显示)

class v_ref
{
public:
  v *p_;
  int i_;
  v_ref(v *p, int i)
    : p_(p), i_(i)
  {
  }
  operator = (double q)
  {
     // again, I suppose you'd use an array instead!
     if(i_ == 0)
     {
       p_->x_ = q;
     }
     else
     {
       p_->y_ = q;
     }
  }
};

假设您想要一些安全性,向量指针可以使用引用计数器,以便您知道主向量对象是否在其所有引用对象之前被删除...

另一个注意事项:我想您的构造函数将分配一个 double 数组(或使用 std::vector&lt;double&gt; 类型...)如果您使用 new,请记住在析构函数中删除,那时 if() 在赋值运算符很重要。

【讨论】:

  • 我如何创建一个矢量类对象来实现这些东西?
  • @user2495847 所以你还没有vector 课程?听起来你需要从一些基本的 C++ 类教程开始。
  • @crashmstr 我被要求创建一个矢量类对象,这是否意味着创建一个像这样的矢量...矢量 使用上面显示的代码还是意味着...类我的向量:std::vector { ... };是什么?
猜你喜欢
  • 2020-03-09
  • 1970-01-01
  • 2013-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-25
相关资源
最近更新 更多