最近,我正在阅读《C++ 对象模型内部》,在阅读第 5 章时,我提出了以下问题:
即使类有复制构造函数,编译器也会处理 NRVO 吗?
答案是“不,它不会阻止它。”
n3290(C++11 草案),第 12 卷,第 8 章,第 31 节(p284):
当满足某些条件时,允许实现省略类的复制/移动构造 对象,即使对象的复制/移动构造函数和/或析构函数有副作用。
RVO(或 NRVO)是编译器可能用来消除副本的优化,即防止创建冗余副本。您的复制构造函数的自定义实现不能阻止应用此优化。
RVO 或多或少是在另一个作用域中创建对象,并在读取或写入变量时使用该对象而不是本地对象。这会导致只创建一个对象,并且根本不调用任何复制构造函数,无论您是否声明它无关紧要,都会进行渲染。
我认为你的问题是“如果简单的复制构造函数会阻止 nrvo”, 我的答案是否定的。 我使用《c++对象模型内部》一书中的案例,让它打印foo函数中和main函数中的成员地址,结果显示它们在release模式下是相同的,而在debug模式下是不同的,没有乐观,在 vs2010 中。 这意味着 NRVO 不关心您是否有一个不平凡的复制构造函数或一个平凡的复制构造函数。