![]() |
1
12
C++标准允许编译器在这种情况下删除不必要的拷贝(它被称为“命名返回值优化”,通常缩写为NRVO)。当您返回一个临时变量而不是一个命名变量时,会有一个匹配的“rvo”。 几乎所有最近合理的C++编译器都实现了NRVO和RVO,所以一般来说,你可以忽略这样一个事实,即这个构造不会特别有效。 编辑:当然,我是在讨论返回新矩阵时所涉及的副本,它保存了加法的结果。你大概 做 要按常量引用传递输入:
…否则,按值传递,但返回传递的值:
注意这取决于交换性
|
![]() |
2
3
您可以在不触发复制构造的情况下返回值。它被称为r值引用 这里解释得很详细 http://www.artima.com/cppsource/rvalue.html |
![]() |
3
2
注意,您的第一个天真实现是非常本机的,因为没有任何东西是通过引用传递的。我假设这是一个非常天真的例子,没有必要提醒读者通过引用而不是通过值传递的好处。 请注意,我也使用了非成员函数运算符,而不是成员函数,但最后,结果(几乎)是相同的。 如果要确保不创建必要的副本,应尝试非操作员版本:
如果您想用operator方式(这是我首选的解决方案),那么您应该假设operator+将创建一个临时的。然后您应该定义operator+和operator+=:
现在,您可以尝试“利用”编译器优化,并将其编写为:
由Herb Sutter在 C++编码标准 , 27。偏爱算术和赋值运算符的规范形式 ,P48-49:
|
![]() |
4
1
如果你真的关心性能(你分析了吗?)您可能根本不应该实现operator+,因为您无法控制它是否会导致创建一个非最佳的临时对象。只需实现运算符+=和/或成员函数
如果你需要接线员,杰里·科芬的任何一个都可以。 |
![]() |
5
1
正如其他人所指出的,您的实现并不像您想象的那样昂贵。但是,定义其他方法来修改对象以在关键的内部循环中使用可能有一定的意义。 编辑 -固定在以下段落 这里的要点是,即使使用了返回值优化,您仍然可以构造一个局部变量,然后在operator+退出后将其分配给结果变量。当然,还要破坏那个额外的物体。仍然有一个额外的对象用于临时保存结果。使用写时拷贝进行引用计数是可能的,但这会给矩阵的每次使用增加解引用开销。 对于99%的案例来说,这些都不是问题,但是偶尔你会遇到一个关键的案例。如果你处理的是大型矩阵,参考计数的开销将是微不足道的-但对于2d到4d,有时你可能会非常关心这些额外的周期-或者更重要的是,关于 不 当您希望矩阵位于堆栈上或嵌入到某个struct/class/array中时,将其放在堆上。 也就是说-在这些情况下,你可能不会编写自己的矩阵代码-你只需要使用来自directx或opengl的矩阵操作或其他什么。 |
![]() |
6
0
有两种解决方法。 1)使用参考文献:
2)在复制构造函数中使用浅复制。是,将创建新的矩阵对象,但不会再次创建实际矩阵 |
![]() |
7
0
我试图在return语句中构造矩阵:
这样你就不用临时工了。 |
![]() |
8
0
|
![]() |
AstralHex · 矩阵乘法代码工作不正常 7 月前 |
![]() |
Max · 用两列中的特定值对识别R中的数据帧行 9 月前 |
![]() |
RobertF · 如何将函数应用于矩阵的每个元素? 9 月前 |
![]() |
Leprechault · 使用数据帧创建对象类“matrix”“array” 10 月前 |
![]() |
Landers · 将矩阵转换为包含所有值的列表 1 年前 |
![]() |
P_B · 如何从矩阵中减去均值向量 1 年前 |
![]() |
Rotacional · 获取矩阵中的方向元素 1 年前 |
![]() |
ImRobb · 为什么int**m不等于int m[][]?[关闭] 1 年前 |