什么是复制省略?什么是(命名)返回值优化?它们意味着什么
在什么情况下会发生这种情况?限制是什么
- 如果你被提到这个问题,你可能正在寻找介绍
- 有关技术概述,请参阅标准参考资料
- 请参见此处的常见案例
导言
有关技术概述,请跳到此答案
对于发生复制省略的常见情况,请跳到此答案
拷贝省略是大多数编译器实现的一种优化,用于在某些情况下防止额外的(可能昂贵的)拷贝。它使按值返回或按值传递在实践中可行(适用限制)
这是唯一一种省略的优化形式(哈!)即使复制/移动对象有副作用,也可以应用“仿佛”规则-复制省略
以下示例摘自维基百科:
预结构{
C(){}
C(const C){std::cout<;<;<;<;<;<;<;<;<;<;<;<;<;<;<;<;<;<;<;<;<;>;>;>;>
};
C f(){
返回C();
}
int main(){
std::cout“你好,世界!\n”;;
C obj=f();
}
取决于编译器&;设置,以下输出均有效:
你好,世界
复制了一份
复制了一份
你好,世界
复制了一份
你好,世界
这也意味着可以创建更少的对象,因此您也不能依赖于调用特定数量的析构函数。复制/移动构造函数或析构函数中不应该有关键逻辑,因为不能依赖于调用它们
如果省略了对复制或移动构造函数的调用,则该构造函数必须仍然存在并且可以访问。这确保复制省略不允许复制通常不可复制的对象,例如,因为它们具有私有或已删除的复制/移动构造函数
C++17:从C++17开始,当直接返回对象时,可以保证省略复制:
结构C{
C(){}
C(const C){std::cout<;<;<;<;<;<;<;<;<;<;<;<;<;<;<;<;<;<;<;<;<;>;>;>;>
};
C f(){
return C();//绝对执行复制省略
}
C g(){
C C;
返回c;//可能执行复制省略
}
int main(){
std::cout“你好,世界!\n”;;
C obj=f();//未调用复制构造函数
}