Stackoverflow ( https://stackoverflow.com/ ) 可能是这个问题的更好讨论论坛。但是,这是一个简短的答案。
我怀疑 C++ 编译器是否像你上面描述的那样为这个表达式生成代码。所有现代 C++ 编译器都实现了一种称为“返回值优化”(http://en.wikipedia.org/wiki/Return_value_optimization)的优化。通过返回值优化,结果evolutionMatrix*stateMatrix直接存储在stateMatrix; 没有复制。
在这个话题上显然存在相当大的混乱,这也是我建议 Stackoverflow 可能是一个更好的论坛的原因之一。那里有很多 C++“语言律师”,而我们这里的大多数人宁愿把时间花在 CSE 上。;-)
我根据 Bangerth 教授的帖子创建了以下简单示例:
#ifndef NDEBUG
#include <iostream>
using namespace std;
#endif
class ExpensiveObject  {
public:
  ExpensiveObject () {
#ifndef NDEBUG
    cout << "ExpensiveObject  constructor called." << endl;
#endif
    v = 0;
  }
  ExpensiveObject (int i) { 
#ifndef NDEBUG
    cout << "ExpensiveObject  constructor(int) called." << endl;
#endif
    v = i; 
  }
  ExpensiveObject (const ExpensiveObject  &a) {
    v = a.v;
#ifndef NDEBUG
    cout << "ExpensiveObject  copy constructor called." << endl;
#endif
  }
  ~ExpensiveObject() {
#ifndef NDEBUG
    cout << "ExpensiveObject  destructor called." << endl;
#endif
  }
  ExpensiveObject  operator=(const ExpensiveObject  &a) {
#ifndef NDEBUG
    cout << "ExpensiveObject  assignment operator called." << endl;
#endif
    if (this != &a) {
      return ExpensiveObject (a);
    }
  }
  void print() const {
#ifndef NDEBUG
    cout << "v=" << v << endl;
#endif
  }
  int getV() const {
    return v;
  }
private:
  int v;
};
ExpensiveObject  operator+(const ExpensiveObject  &a1, const ExpensiveObject  &a2) {
#ifndef NDEBUG
  cout << "ExpensiveObject  operator+ called." << endl;
#endif
  return ExpensiveObject (a1.getV() + a2.getV());
}
int main()
{
  ExpensiveObject  a(2), b(3);
  ExpensiveObject  c = a + b;
#ifndef NDEBUG
  c.print();
#endif
}
它看起来比实际上更复杂,因为我想在优化模式下编译时完全删除所有用于打印输出的代码。当我运行使用调试选项编译的版本时,我得到以下输出:
ExpensiveObject  constructor(int) called.
ExpensiveObject  constructor(int) called.
ExpensiveObject  operator+ called.
ExpensiveObject  constructor(int) called.
v=5
ExpensiveObject  destructor called.
ExpensiveObject  destructor called.
ExpensiveObject  destructor called.
首先要注意的是没有构建临时变量——只有 a、b 和 c。默认构造函数和赋值运算符永远不会被调用,因为在此示例中不需要它们。
Bangerth 教授提到了表达式模板。事实上,这种优化技术对于在矩阵类库中获得良好的性能非常重要。但仅当对象表达式比简单的 a + b 更复杂时才重要。例如,如果我的测试是:
  ExpensiveObject  a(2), b(3), c(9);
  ExpensiveObject  d = a + b + c;
我会得到以下输出:
ExpensiveObject  constructor(int) called.
 ExpensiveObject  constructor(int) called.
 ExpensiveObject  constructor(int) called.
 ExpensiveObject  operator+ called.
 ExpensiveObject  constructor(int) called.
 ExpensiveObject  operator+ called.
 ExpensiveObject  constructor(int) called.
 ExpensiveObject  destructor called.
 v=14
 ExpensiveObject  destructor called.
 ExpensiveObject  destructor called.
 ExpensiveObject  destructor called.
 ExpensiveObject  destructor called.
这种情况显示了临时构造的不良构造(对构造函数的 5 次调用和对运算符 + 的两次调用)。正确使用表达式模板(这个话题远远超出了本论坛的范围)可以暂时防止这种情况发生。(对于积极性高的人,可以在http://www.amazon.com/C-Templates-The-Complete-Guide/dp/0201734842的第 18 章中找到关于表达式模板的特别易读的讨论)。
最后,编译器实际在做什么的真正“证明”来自检查编译器输出的汇编代码。对于第一个示例,在优化模式下编译时,这段代码非常简单。所有函数调用都被优化掉了,汇编代码基本上将 2 加载到一个寄存器中,将 3 加载到第二个寄存器中,然后添加它们。