我是C ++的新手,我的问题是:为什么我们需要在C ++中重载运算符?什么时候应该在C ++中重载运算符,为什么我们不使用内置变量来进行计算,比较,输出和输入值。我只是不明白,我们需要重载运算符的最合适的情况是什么,或者在处理类时我们是否总是重载运算符?
答案 0 :(得分:2)
如果你看一下很多C ++资源,你可能会得出结论 最频繁使用运算符重载(或 一般来说,超载(就此而言)是混淆。 还是......
首先,在许多情况下,你必须这样做 重载赋值运算符。编译器将生成 一个给你,如果你不,在许多情况下, 生成一个不会做你想要的。 (这也经常发生 声明一个私有的重载赋值,而不是实现它, 为了阻止分配。)
如果一个类代表某种数值(例如
BigInteger
或Decimal
),那么它绝对有意义
重载算术运算符。它的可读性更高
写:
BigFloat
discriminant( BigFloat const& a, BigFloat const& b, BigFloat const& c )
{
return b*b - 4*a*c
}
大于
BigFloat
discriminant( BigFloat const& a, BigFloat const& b, BigFloat const& c )
{
return sub(mult(b, b), mult(4, mult( a, c )));
}
在这种情况下,您应该始终重载所有适用的
运营商,具有自然意义:它会非常不酷
如果您的类型支持+
,但不支持+=
,或支持+
用减法的语义。
关于这个问题的合法扩展很少
算术运算符:关于我唯一可以接受的是
使用+
(和+=
)进行连接的字符串类。
(通常,我希望+
是可交换的,这是串联的
当然不是。但该公约已如此完善
具有内置字符串类型的语言很难实现
避免它。)
具有可比性的类型应支持==
和!=
,以及if
有一个逻辑顺序,<
,<=
,>
和>=
。 (关于
另一方面,当只有一个任意的时候重载<
订购,这样您就可以在没有比较的情况下致电std::sort
运算符,是混淆。)同样,它更自然
写a < b
而不是isLessThan( a, b )
。有时候
难以决定:当我第一次启动C ++时,我有Set
class,基于位图,我将<
定义为严格
子集,<=
一个子集等。我不知道我是否会再次这样做;
不平等运算符应该只有在定义时才能定义
关系是传递性的。
除此之外,任何时候你的类型都会以某种方式模仿
内置,像指针或数组,你可能会想要
重载相应的受支持的运算符:向量或
不支持[]
的数组类会令人惊讶,因为
将是一个不支持*
和->
的智能指针。
最后,有一些使用的标准C ++习语 运算符重载:
如果您定义了可以从文本流中插入或提取的类型,则可以通过定义<<
和>>
运算符来实现。
C ++迭代器的设计看起来像指针;如果你想
它们可以与标准算法一起使用的迭代器
应该支持与智能指针相同的运算符,
以及++
,可能还有--
,在某些情况下,还有[]
指针算术运算符(包括operator()
,即
根据原始指针上的指针算法定义)。这个
显然是混淆,它肯定使用了
迭代器不必要地复杂,但是很难避免
你正在使用C ++标准库。
C ++库也广泛使用了函数
具有operator()
(函数调用运算符)的对象。
谓词对象的bool
返回<
。
(谓词对象最常用的一个用途是
实现订购关系。如果你的班级没有
支持您可能想要提供的逻辑std::set
运算符
一个单独的功能对象,定义一个任意顺序,
这样对象仍然可以插入std::map
,或者是
用作{{1}}中的键。)可以说,这也应该有
是一个命名函数,但很难想象一个好名字
将适用于所有地方,因为该对象确实表现得像
一个功能,它并不是真的太糟糕了。
我可能已经忘记了一两个其他案例,但是 一般来说,关于运营商超载,如有疑问, 不。