我一直在经历Deitel的C ++ Fundamentals和先生。 Deitel重写了重载标准运算符,为自定义类及其成员提供标准功能。我的意思是,例如,而不是cout << object.memberFunction();
我可以简单地说cout << object;
这种技术确实允许链接和更快的打字,但它需要操作符重载实现,即使你仍然是一个新手,我觉得代码实际上变得不太可读,特别是如果有很多类成员你必须记住哪些是运算符重载等等。没有重载运算符代码更易读,另外还可以保存重载代码。
所以我的问题是我是否应该花时间学习运算符重载?我是C ++的新手,欢迎来自更多实践和经验的人的答案。运算符重载的好处是否会超过实现它的工作量和降低的代码可读性?
答案 0 :(得分:4)
您当然应该花时间学习运算符重载。但这并不意味着您应该或不应该使用运算符重载。但是如果没有学习,你就无法真正做出决定。决定使用你不熟悉的东西很难,如果不是不可能的话。你总会找到一些你不懂的东西,即使它实际上更容易使用也是如此。
话虽如此,根据具体情况做你认为最好的事情。如果在您的情况下,您发现操作符重载的代码可读性较低,请不要这样做。然而,它有用的情况。但是因为一般来说重载操作符是为了便于阅读,如果你发现它不适用于你的情况,请远离它。
答案 1 :(得分:1)
在许多情况下,运算符重载提高了可读性,这些都是有用的情况。第一次你可能有一个不幸的例子;特别是对于运算符&lt;&lt;,这种情况发生了,并且您已经学习了第一个运算符重载课程:有时,显式方法调用更清晰。但有时它不是。例如,考虑C ++中的典型矩阵乘法(例如,使用特征矩阵):
a = b * c;
和Java:
a = b.multiplyUsingTheMatrixMultiplicationAlgorithmThatsMathYay(c);
运算符重载使代码更具可读性。对于这些情况,您应该研究或至少了解运算符重载,并且仅在这些情况下应该应用它。
答案 2 :(得分:1)
我很想说学习没有任何关于运算符的内容
超载;重载运算符只是有趣的命名函数。什么
你需要学习的是重载是否合适,何时适合
不。某些习语或多或少是标准的:数字类型超载
适当的数字运算符(+
等),智能指针重载
指针ops(*
和->
),支持索引的容器类型
overload []
和函数对象重载()
。这就是
它适用于特殊情况。虽然它可以说是滥用,如果你
定义一个迭代器,你会希望它支持标准迭代器
成语(意思是++
,*
,->
和==
/ !=
)。
除此之外,还有三个运算符将被重载
对于许多不同类型的类:使用=
完成赋值,和
使用<<
和>>
完成对流的插入和提取。
如果您希望您的班级支持其中任何一项,您应该使用
超载。比较使用==
和!=
表示相等,<
,
不平等的<=
,>
和>=
。但不要因不平等而过载
除非它具有语义意义。最好提供一个
用于std::map
和std::set
的显式排序函数
误导读者认为你已经定义为语义
重要的订购。您可能希望专注于std::less
这种情况下的阶级; <
不起作用,或者会有不恰当的语义
用作键,但std::less
将定义任意顺序
会的。虽然它不是运算符重载,但如果类型是
用作关联容器中的键,您也需要提供
函数hash_code
和实例化struct std::hash
。
在许多情况下,最好根据更多方面定义过载
全局函数:例如:我使用compare
(返回int
更少
不等于,等于或大于0);我将定义一个公众
在类中使用函数compare
,然后从以下内容派生:
template<typename T>
struct ComparisonOperators
{
friend bool operator==( T const& lhs, T const& rhs )
{
return lhs.compare() < 0;
}
// ...
// The same for the other five operators.
};
(我的实现实际上有点复杂,因为它使用
元编程使用isEqual
用于==
和!=
(如果类提供)
它)。
我使用类似的技术来定义二进制算术运算符
就+
等而言+=
我也将其用于IO,用术语定义<<
在print
方面的>>
和parse
;这主要是有用的时候
运算符需要是多态的。
答案 3 :(得分:0)
实际上,我认为标准的重载运算符是理所当然的,并没有说明每种类型都有单独的实现。因此,运算符重载在许多方面实际上非常重要,例如在使用模板时,因此节省的时间比我最初实现的要深得多。
答案 4 :(得分:-1)
为此目的使用朋友外部操作员是一种常规做法,如下所示
friend std::ostringstream & operator<<(std::ostringstream &oss, Type &type);
和
std::ostringstream & operator<<(std::ostringstream &oss, Type &type)
{
oss << type.attr1;
oss << type.attr2;
oss << type.attr3;
return oss;
}
所以你可以调用:
Type val;
...
std::cout << val << std::end;