【问题标题】:Overloading logical operators considered bad practice?重载逻辑运算符被认为是不好的做法?
【发布时间】:2011-07-05 05:21:29
【问题描述】:

重载 &&, || 是不是一个坏主意或逗号运算符,为什么?

【问题讨论】:

  • 这感觉像是一道期末考试题 ;)

标签: c++ operators operator-overloading logical-operators


【解决方案1】:

为了在 C++ 中重载逻辑运算符,必​​须对操作数进行求值,这不是通常使用内置类型短路时的工作方式。

看看下面的链接。

【讨论】:

    【解决方案2】:

    除非你的类代表一些逻辑实体,否则这是个坏主意,因为重载的运算符会迷失方向,并可能导致代码中出现新的错误。

    【讨论】:

    • 即使在定义“逻辑实体”(布尔代数)时,其他运算符也更适合。
    【解决方案3】:

    我会说这取决于您的重载在做什么。例如,&& 和 ||预计将作为逻辑条件工作,因此如果您的重载语义以某种方式工作,它们可能会混淆其他人(甚至您自己,如果您有一段时间不使用它们而忘记了它们的作用)。考虑一下,如果您不知道运算符是如何被重载的,并且只使用普通方法会更清楚,那么您希望运算符做什么。

    【讨论】:

      【解决方案4】:

      我不会超载operator&&operator||。即使您定义了一个产生布尔代数的类(例如有限集),重载operator&operator| 可能是更好的选择。

      原因是 C++ 程序员希望 operator&&operator|| 有特殊的语义:它们是短路,即如果没有必要,不计算它们的右手参数。您无法通过重载获得此行为,因为您将定义一个函数。

      重载operator, 已经在例如Boost.Assign 库。这也是我所知道的唯一一个重载的例子,我什至从来没有考虑过自己重载它。你最好有一个非常具体的用例,没有其他运算符适合。

      【讨论】:

      • 好点。那么,在这种情况下(operator bool())提供一个转换为布尔的运算符似乎更好?
      • @davka:是的,如果您的类具有布尔逻辑语义,请定义operator bool,这样您就可以免费短路。如果 operator&operator| 具有布尔代数语义,则定义 operator|,就像有限集一样(其中交集是 &,并集是 |)。
      • @larsmans:非常抱歉,意外点击。我必须“编辑”你的答案才能删除它(我删除了一个空白行)。
      • @davka:关于布尔转换......不,不要!请参阅artima.com/cppsource/safebool.html,主要问题是可以将布尔值提升为整数。最好将转换运算符定义为指向成员函数的指针。
      【解决方案5】:

      正如其他人所说,缺少惰性求值是避免重载逻辑运算符的主要原因。

      但是,超载它们有一个很好的理由:Expression templates。 Boost.Lambda 库可以做到这一点,而且非常有用!

      【讨论】:

        【解决方案6】:

        这通常是个坏主意:这三个运算符具有排序效果,当您重载它们时就会丢失。失去这种排序效果可能会导致那些没想到会丢失的人(即奇怪的错误)。

        在某些情况下,模板表达式可以保持排序效果,在这些情况下,我认为重载它们没有问题。

        operator, 的重载我知道还有另一个问题:它们的工作方式使得明显的操作链不是真实的。通常,它们会在没有区别的情况下用于上下文,但一旦出现在蓝月亮中,那就是奇怪错误的另一个来源。

        【讨论】:

          【解决方案7】:

          您不应该以令人惊讶的方式重载任何运算符。 :-)

          如果您能以一种有意义的方式(不仅对您)这样做,那么这样做是可以的。

          正如其他人所说,逻辑运算符的特殊之处在于它们具有惰性求值的效果。所以你的重载可能应该保留这种惰性效果,就像表达式模板一样,或者只在人们不期望这种效果的地方使用。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-12-08
            • 1970-01-01
            • 1970-01-01
            • 2010-10-22
            • 2011-11-20
            • 1970-01-01
            相关资源
            最近更新 更多