传递或返回变量时并不总是调用复制构造函数
Copy constructor is not always called when passing or returning variables
在这个答案中,有人提到,当按值将变量传递到函数中或作为函数的返回值传递时,不一定调用复制构造函数。有人可以解释一下这种情况何时发生以及为什么发生吗?在这种情况下,编译器如何设法返回结果?
如前所述,这就是返回值优化和复制省略。
当对象是新创建然后复制时,可能会发生这种情况。在这种情况下,允许编译器对其进行优化,以便直接在正确的位置创建新对象,并且不需要复制(并且也不会调用复制构造函数)。
例如:
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 或其他)。该标准只是说允许编译器省略对复制构造函数的调用。
如果您对有关调用约定的一些依赖于平台的详细信息感兴趣,下面是一些链接。但请注意,这些细节并不重要。您所要知道的是,编译器被允许优化复制构造函数调用(并且在大多数情况下会这样做)。
- 维基百科x86调用约定
- Apple 开发人员文档:IA-32 函数调用约定
- 关于 SO 的问题:函数返回
struct
的调用约定
相关文章:
- 当从函数参数中的临时值调用复制构造函数时
- 为什么调用复制构造函数而不是移动构造函数?
- 为用户定义的类正确调用复制构造函数/赋值运算符
- 编译器调用复制运算符而不是移动运算符
- push_back std::vector,则重复调用复制构造函数
- 为什么调用复制构造函数来构造空unique_ptr向量?
- 为什么转换运算符调用复制构造函数两次,而等效函数只调用它一次
- 我打算调用initializer_list构造函数,如果存在,则事先调用复制构造函数:为什么?
- C++ - 从移动分配运算符调用复制分配
- 构造函数初始值设定项列表未调用复制构造函数
- 为什么在我的代码中调用复制构造函数而不是移动构造函数?
- std::map 在 [] 上调用默认构造函数,在 insert() 上调用复制构造函数
- 通过引用传递对象时是否调用复制构造函数?
- 如果函数按值传递并按值返回,将调用复制构造函数多少次
- 为什么要抛出引用调用复制构造函数的异常?
- 为什么即使参数标记为"const",也会调用复制构造函数?
- Clang-Tidy:移动构造函数通过调用复制构造函数来初始化类成员
- 为什么当我添加一个不同的对象(复制构造函数中的参数)时调用复制构造函数?
- 为什么调用复制构造函数,当我只返回对象 c++ 的引用时
- 为什么在下面的代码中调用复制构造函数两次