我是C++的新手,我的问题是:为什么我们需要在C++中重载操作符,什么时候我们应该在C++中重载操作符,为什么我们不直接使用内置变量来进行计算、比较、输出和输入值。我只是不明白,在什么情况下,我们需要重载操作符,还是在处理类时总是超载操作符?
发布于 2014-08-19 13:58:34
如果您查看了许多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 )));
}在这种情况下,您应该始终重载所有适用的操作符,并具有它们的自然含义:如果您的类型支持+,但不支持+=,或者如果它支持+并使用减法的语义,这将是非常不酷的。
关于算术运算符,几乎没有合法的扩展:我认为唯一可以接受的扩展是使用+ (和+=)进行连接的字符串类。(通常情况下,我希望+是可交换的,而级联当然不是。但是这种约定在具有内置字符串类型的语言中是如此的根深蒂固,以至于您很难避免它。)
具有可比性的类型应该支持==和!=,如果存在逻辑排序,则支持<、<=、>和>=。(另一方面,在只有任意排序的情况下重载<,这样您就可以在不使用比较运算符的情况下调用std::sort,这是混淆的。)同样,编写a < b比编写isLessThan( a, b )更自然。有时很难决定:当我第一次启动C++时,我有一个基于位图的Set类,我将<定义为严格子集,<=定义为子集,等等。我不知道我是否会再次这样做;不等式运算符可能只有在这种关系是传递的情况下才能定义。
除此之外,当您的类型以某种方式模拟内置的东西时,比如指针或数组,您可能想要重载相应的受支持的运算符:不支持[]的向量或数组类将使人毛骨悚然,就像不支持*和->的智能指针一样。
最后,还有一些使用操作符重载的标准C++成语:
<<和>>运算符来实现。++,可能还有--,在某些情况下,还支持所有指针算术运算符(包括[],它是根据原始指针上的指针算法定义的)。这显然是一种混淆,它当然会使迭代器的使用变得不必要的复杂,但是如果您使用的是C++标准库,则很难避免。operator() (函数调用操作符)广泛使用函数对象。谓词对象有一个operator(),它返回一个bool。(谓词对象最常见的用法之一是实现排序关系。如果您的类不支持逻辑<操作符,您可能希望提供一个单独的函数对象,该对象定义任意顺序,以便仍然可以将对象插入到std::set中,或者在std::map中用作键。)可以说,这也应该是一个命名的函数,但是很难想象一个好的名称在任何地方都适用,而且由于对象的行为确实像一个函数,所以它并不是很糟糕。也许还有一两种情况我已经忘记了,但一般来说,关于操作者超载,当有疑问的时候,不要。
https://stackoverflow.com/questions/25382562
复制相似问题