在C和C ++中,我们可以从函数和方法返回结构或类:
class A final { public:
int i;
A(int n) { this->i=n; }
};
A function(void) {
return A(4);
}
int main(void) {
A result = function();
return 0;
}
我想知道的是这是如何实现的?传统的观点是它被复制,从而产生成本:为了缓解,您可以将指针传递给结构而不返回任何内容。
但是,我不确定这是否(总是)必要的。例如,在上文中,从未在本地使用构造的结构。既然我们正在返回它,那么在弹出堆栈之前,数据是否无法直接填充到result
变量的一个更高级别?
正如我所看到的,这样做的主要问题是被调用者函数需要知道调用者想要结果的位置。另一个问题是在更多递归函数的情况下:如果你要复制的最终变量是堆栈中的几层,那么被调用者找到正确位置会变得更加困难。根据我有限的编译器知识,我的猜测是,在返回后立即从调用者复制来自被调用者的struct 。
总的来说,我觉得这样的优化可能会很棘手。对于内联函数,我希望它是隐式发生的,如果结构从未在本地使用过,我看不出为什么它不能以这种方式实现的原因。但是,对于其他所有内容,我希望您尝试实现它时遇到的问题太大了,实际上通常只会复制它。
所以:
答案 0 :(得分:0)
在C ++中,编译器经常使用copy elision习语(通常称为“返回值优化”)来避免在返回值时不必要的副本。至少,他们通常允许来做。
C ++标准,第12.8节:
当满足某些条件时,允许省略实现 复制/移动类对象的构造,即使构造函数 选择用于复制/移动操作和/或析构函数 对象有副作用。在这种情况下,实施处理 省略的复制/移动操作的源和目标只是两个 引用同一个对象的不同方式,以及对它的破坏 该对象发生在两个对象的后期 如果没有优化就会被破坏。
复制/移动操作的省略,称为复制省略,是 在下列情况下允许(可以合并到 消除多份副本)
在函数的返回语句中,具有类返回类型,当时 expression是非易失性自动对象的名称(除了 一个函数或catch子句参数)具有相同的cv-不合格 键入函数返回类型,复制/移动操作即可 通过直接构造自动对象省略 函数的返回值
...