【问题标题】:Why should methods return a new instance, rather than modify the instance itself?为什么方法应该返回一个新实例,而不是修改实例本身?
【发布时间】:2017-04-26 12:55:57
【问题描述】:

假设我有一个Vector3 类,其中包含一个normalize() 方法。该方法是否应该返回一个新的Vector3,或者修改调用它的Vector3 实例(因此返回对自身的引用(Vector3&)?)在哪些情况下会优先选择一个?性能怎么样?

【问题讨论】:

  • 您能添加一些代码示例吗?我不知道你在说什么,但我相信你可能有兴趣阅读this
  • 竞争目标:正确性与性能(有时)。如果您使用不可变类型,则可以更轻松地编写正确的(并行)程序。如果您使用可变类型,您有时会获得一定的性能优势,一旦您尝试并行化,很可能会失去这种优势。然后是 80/20 规则。 80% 的代码不需要优化。那么为什么默认使用可变类型呢?先去不可变,然后看它是否有足够的性能,如果没有,再进行优化。
  • @BitTickler 回答,不评论...
  • @BitTickler 只有 80%?如果按代码行数计算,我非常保守的估计是大约 95% 不需要优化 :-)

标签: c++ oop


【解决方案1】:

答案取决于班级的设计。

对于可变类rotate 应该旋转向量本身。这被认为更有效,并且对于大型对象,当向量中有很多项目时,它可以让您避免复制大量数据。

另一方面,不可变类必须只返回新对象,因为它们本身不能被变异。这增加了一些开销,但它有很多优点,尤其是当对象必须同时使用时。

一个常见的命名约定是使用动词来进行变异操作,如

myVector.rotate(angle);
myVector.scale(factor);

虽然返回新对象的操作应使用past participles 命名,如

auto newVector = myVector.rotated(angle).scaled(factor);

【讨论】:

    【解决方案2】:

    竞争目标:正确性与性能(有时)。

    如果您使用不可变类型,则可以更轻松地编写正确的(并行)程序。如果您使用可变类型,有时您会获得一定的性能优势,一旦您尝试并行化,很可能会失去这种优势。然后是 80/20 规则。 80% 的代码不需要优化。那么为什么默认使用可变类型呢?

    先去不可变,然后看它是否有足够的性能,如果没有,再优化。

    【讨论】:

      【解决方案3】:

      副作用。例如,如果我传递了一个从地图中检索到的对象,而你对我传递的对象执行了一些操作,那么你已经更改了我的地图中的内容,并且下次我请求它时,我得到的东西并没有看起来和我上次一样。保持对象不可变可防止此类事故发生,尤其是当多个开发人员正在开发同一个应用时。

      【讨论】:

        【解决方案4】:
         Vector3 rotate(const Angle& angle)
        

        可能没问题,但很大程度上取决于Vector3 是否正确实施。尤其是关于std::move() 的行为。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-01-20
          • 2023-03-07
          • 1970-01-01
          • 1970-01-01
          • 2012-06-16
          • 2016-01-13
          • 1970-01-01
          相关资源
          最近更新 更多