在this回答中,有人提到,当按值将变量传递给函数或作为函数的返回值时,不一定要调用复制构造函数。有人可以解释何时发生这种情况,为什么?在这种情况下,编译器如何设法返回结果?
答案 0 :(得分:2)
如上所述,这是Return value optimization和Copy elision。
在新创建然后复制对象时,可能会发生这种情况。在这种情况下,允许编译器对其进行优化,以便在正确的位置直接创建新对象,并且不需要复制(并且也不会调用复制构造函数)。
例如:
struct A {};
void test(A a) {}
int main() {
test(A()); // probably there will be no copy here
}
对于返回,它是类似的。您创建一个新对象,然后如果您返回它,那将涉及一个副本,但允许编译器优化该副本(因此也调用复制构造函数)。
例如:
A returnANewA() {
return A(); // copying would take place here
}
int main() {
A a = returnANewA(); // the compiler is allowed to do that without copying
}
编译器如何执行此操作:根据调用约定,它知道返回值必须存储在堆栈中的位置。在其他情况下,它当然有助于编译器知道功能代码。但所有这些都取决于架构(x86或其他)和编译器(GCC,Microsoft或其他)。该标准只是说允许编译器省略对copy-constructor的调用。
如果您对某些与平台相关的有关调用约定的详细信息感兴趣,请参阅以下链接。但请注意,这些细节并不重要。您只需要知道编译器可以优化复制构造函数调用(在大多数情况下会这样做)。