如果函数按值传递并按值返回,将调用复制构造函数多少次

How many times will copy constructor be called if a function pass by value and return by value

本文关键字:调用 复制 构造函数 多少次 返回 按值传递 函数 如果      更新时间:2023-10-16

我知道f(ClassA str)按值传递并按值返回,所以

f(str)调用复制构造函数 2 次;

f(f(str))调用复制构造函数 4 次;

str1 = f(f(str))调用复制构造函数 5 次。

但结果是 2,3,3。

此外,如果我将f的定义更改为ClassA f(ClassA &str),则会出现错误initial value of reference to non-const must be an lvalue.这个错误怎么会出现?

#include<iostream>
using namespace std;
class ClassA
{
int a, b;
public:
ClassA()
{
a = 10;
b = 20;
}
ClassA(const ClassA &obj)
{
a = obj.a; b = obj.b;
cout << "copy constructor called" << endl;
}
};
ClassA f(ClassA str)
{
return str;
}
int main(){
ClassA str;
ClassA str1;
str1 = f(f(str));
}

UPD: 类 A 显式声明仅复制构造函数。 因此,ClassA具有默认的复制赋值运算符

如果类定义未显式声明复制赋值运算符,则隐式声明一个。 如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明 复制赋值运算符定义为已删除;否则,它被定义为默认值

并且没有默认移动构造函数

如果类 X 的定义没有显式声明移动构造函数,则非显式构造函数将是隐式的 声明为默认值当且仅当 (8.1( — X 没有用户声明的复制构造函数, (8.2( — X 没有用户声明的复制赋值运算符, (8.3( — X 没有用户声明的移动赋值运算符,并且 (8.4( — X 没有用户声明的析构函数。

相反,移动构造函数类 A 使用复制构造函数

注意:当移动构造函数未隐式声明或显式提供时,否则表达式 将调用移动构造函数可以改为调用复制构造函数。— 尾注 ]

复制省略发生在 f(f(str((

在具有类返回类型的函数的 return 语句中,当表达式是 与函数类型相同(忽略 CV 限定(的非易失性自动对象 (...( 返回类型,可以通过直接构造自动对象来省略复制/移动操作 进入函数调用的返回对象

摘要:f(str(- 默认:复制构造函数 + 移动构造函数;在这种情况下:复制构造函数 + 复制构造函数

f(f(str((- 默认情况下

:复制构造函数 + 复制 elision + 移动构造函数 + 移动构造函数;在本例中:复制构造函数 + 复制 elision + 复制构造函数 + 复制构造函数str1 =f(f(str(( - 在这种情况下:复制构造函数 + 复制省略 + 复制构造函数 + 复制构造函数 + 复制赋值运算符(不是复制构造函数 赋值运算符和复制构造函数有什么区别?

可能会有另一个结果,例如,如果在 gcc 中使用标志"-fno-elide-constructors"。它禁用复制省略 禁用 g++ 的返回值优化

f(str(返回右值对象。在 ClassAf(ClassA &str(中,你采用左值引用。 有趣的是,ClassA f(constClassA&str(没有给出错误Const引用和左值