重载运算符来处理我自己的类作为std类是一个好习惯吗?

时间:2011-10-27 08:42:18

标签: c++ operator-overloading

我一直在经历Deitel的C ++ Fundamentals和先生。 Deitel重写了重载标准运算符,为自定义类及其成员提供标准功能。我的意思是,例如,而不是cout << object.memberFunction();我可以简单地说cout << object;

这种技术确实允许链接和更快的打字,但它需要操作符重载实现,即使你仍然是一个新手,我觉得代码实际上变得不太可读,特别是如果有很多类成员你必须记住哪些是运算符重载等等。没有重载运算符代码更易读,另外还可以保存重载代码。

所以我的问题是我是否应该花时间学习运算符重载?我是C ++的新手,欢迎来自更多实践和经验的人的答案。运算符重载的好处是否会超过实现它的工作量和降低的代码可读性?

5 个答案:

答案 0 :(得分:4)

您当然应该花时间学习运算符重载。但这并不意味着您应该或不应该使用运算符重载。但是如果没有学习,你就无法真正做出决定。决定使用你不熟悉的东西很难,如果不是不可能的话。你总会找到一些你不懂的东西,即使它实际上更容易使用也是如此。

话虽如此,根据具体情况做你认为最好的事情。如果在您的情况下,您发现操作符重载的代码可读性较低,请不要这样做。然而,它有用的情况。但是因为一般来说重载操作符是为了便于阅读,如果你发现它不适用于你的情况,请远离它。

答案 1 :(得分:1)

在许多情况下,运算符重载提高了可读性,这些都是有用的情况。第一次你可能有一个不幸的例子;特别是对于运算符&lt;&lt;,这种情况发生了,并且您已经学习了第一个运算符重载课程:有时,显式方法调用更清晰。但有时它不是。例如,考虑C ++中的典型矩阵乘法(例如,使用特征矩阵):

a = b * c;

和Java:

a = b.multiplyUsingTheMatrixMultiplicationAlgorithmThatsMathYay(c);

运算符重载使代码更具可读性。对于这些情况,您应该研究或至少了解运算符重载,并且仅在这些情况下应该应用它。

答案 2 :(得分:1)

我很想说学习没有任何关于运算符的内容 超载;重载运算符只是有趣的命名函数。什么 你需要学习的是重载是否合适,何时适合 不。某些习语或多或少是标准的:数字类型超载 适当的数字运算符(+等),智能指针重载 指针ops(*->),支持索引的容器类型 overload []和函数对象重载()。这就是 它适用于特殊情况。虽然它可以说是滥用,如果你 定义一个迭代器,你会希望它支持标准迭代器 成语(意思是++*->== / !=)。

除此之外,还有三个运算符将被重载 对于许多不同类型的类:使用=完成赋值,和 使用<<>>完成对流的插入和提取。 如果您希望您的班级支持其中任何一项,您应该使用 超载。比较使用==!=表示相等,<, 不平等的<=>>=。但不要因不平等而过载 除非它具有语义意义。最好提供一个 用于std::mapstd::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;