我想实现一种类似数字的" C ++中的数学对象(比如组或环中的元素)。我确信我不是唯一一个处理这个问题的人,因此可能会有大量关于什么是最好的"重载算术运算符的方法。但是,我找不到满意的答案(虽然我可能懒得去搜索更多)。
让我们说我想让操作员超载" +"对于A班 问题是,我可以想到有太多不同的重载:
第一个问题。所有这些重载都必须使A的实例上的操作尽可能高效,而且就像原始类型一样#34;尽可能?我认为"普通" case,rvalue-qualified A :: operator + =不需要(或不应该)重载。这样对吗?我认为所有1-4都是必要的。例如,对于案例3,由于移动了x,我们不需要分配新的空间来保存返回值,我们可以安全地重用为x保留的分配存储。是不是?
第二个问题。我认为所有这些重载可能会分享大多数此类情况的代码。如何在不牺牲性能等的情况下最小化代码重复?有没有特殊的技巧/成语呢? 如果存在,我更喜欢通用和可扩展的方法。
答案 0 :(得分:4)
不可能给出最一般的答案,因为选择" best"方式将涉及了解有关操作的细节。
例如,最常见的模式(我在下面给出)对于矩阵乘法来说并不是那么好,因为在这种情况下,最简单的方法是声明一个从零开始并读取两个参数的第三个矩阵。此外,您可能希望使用延迟评估,在这种情况下,这些都不适用。
我建议您确保代码为所有案例提供正确的答案,并且一旦您的程序正常运行并且您有更多的语言经验,您就可以担心微优化。
对于实现+
的最有效方法是修改其中一个参数的类,以下两种情况涵盖所有用途,具有强异常保证:
A& A::operator+=(A const &y) { /* modify *this using y */ ; return *this; }
A operator+ ( A x, A const& y ) { x += y; return x; }
有关上述代码的作用及原因的更多说明,请参阅http://example.com/assets/css/magazine.min.css。
在C ++ 03中,使用A const& x
而不是A x
并没有多大区别,但在C ++ 11中,对于第一个参数的情况,这稍微更优化一些是一个右值,因为现在可以从第一个参数中窃取资源。
关于在operator+=
上使用ref-qualifiers的决定。对&
和&&
的单独重载没有任何好处。如果您已经看到人们使用&
,那么基本原理也不是重载,而是为了尝试在右值上使用+=
而给出编译错误;理由是这可能是一个错误。