C++向量运算符重载
C++ Vector Operator Overloading
我正在尝试找到一个简单的示例程序,该程序重载数学向量的以下运算符。
Constructor // create
= (equals) // assign
+; -; +=; -= // add sub
*; /; *=; /= // multi divide
++; -- // plus minus
== // compare
>; >=
<; <=
[] // access a value
似乎找不到任何好的简单教程。我强调简单,因为我现在才学习这些东西。如果有人可以链接我甚至更好的程序,仅对其中一个运算符进行简单的重载作为示例,那将是令人难以置信的!
编写运算符时需要了解一些事项,这些运算符不经常与其他函数一起使用。
例如,赋值运算符将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_;
如果&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 开始,您应该只声明三向比较运算符<=>
,这允许编译器为您实现所有其他比较运算符。这个返回一个负数(较小:a <b)、0(等于: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
作为参数调用引用的赋值。(请注意,如果您只有 2 个值时使用 3 作为索引,我们可能会抛出错误: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;
}
}
};
假设你想要一些安全性,矢量指针可以使用引用计数器,这样你就知道一个主矢量对象是否在其所有引用对象之前被删除......
另一个注意事项:我想你的构造函数会分配一个双精度数组(或使用std::vector<double>
类型......如果使用 new,请记住在析构函数中删除,这时赋值运算符中的if()
非常重要。
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 重载运算符new[]的行为取决于析构函数
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 在 myVector 类中重载运算符 + 时出错
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- 如何在 cpp 中重载运算符 +=?
- C++ 如何重载 [] 运算符并进行函数调用
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 为什么我可以在不重载 "=" 运算符的情况下将一个对象分配给另一个对象?
- 重载运算符有地址吗?
- 如何迭代重载运算符 [] 的类?
- 重载运算符与添加问题
- 模板基类中的重载运算符
- 如何调用用于重载运算符"<<"的 friend 函数?
- 在 C++17 中的命名空间和子命名空间中重载运算符是不明确的
- 重载运算符<<采用谷歌 C++ 风格
- C++ 如何正确重载 + 运算符
- cout (<<) 重载运算符不打印减去的矩阵
- 如何在 c++ 中重载运算符 + 以便能够 whrite c_str = "smth" + c_str;
- 重载运算符*以获取对另一个类的实例的引用