何时以及为什么我们在C ++中重载运算符

时间:2014-08-19 11:44:14

标签: c++

我是C ++的新手,我的问题是:为什么我们需要在C ++中重载运算符?什么时候应该在C ++中重载运算符,为什么我们不使用内置变量来进行计算,比较,输出和输入值。我只是不明白,我们需要重载运算符的最合适的情况是什么,或者在处理类时我们是否总是重载运算符?

1 个答案:

答案 0 :(得分:2)

如果你看一下很多C ++资源,你可能会得出结论 最频繁使用运算符重载(或 一般来说,超载(就此而言)是混淆。 还是......

首先,在许多情况下,你必须这样做 重载赋值运算符。编译器将生成 一个给你,如果你不,在许多情况下, 生成一个不会做你想要的。 (这也经常发生 声明一个私有的重载赋值,而不是实现它, 为了阻止分配。)

如果一个类代表某种数值(例如 BigIntegerDecimal),那么它绝对有意义 重载算术运算符。它的可读性更高 写:

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}}中的键。)可以说,这也应该有 是一个命名函数,但很难想象一个好名字 将适用于所有地方,因为该对象确实表现得像 一个功能,它并不是真的太糟糕了。

我可能已经忘记了一两个其他案例,但是 一般来说,关于运营商超载,如有疑问, 不。