C++ 为什么不';我不能在这段代码中得到返回值优化吗?
谁能给我解释一下输出的第五行吗?我不明白为什么C++ 为什么不';我不能在这段代码中得到返回值优化吗?,c++,constants,copy-constructor,C++,Constants,Copy Constructor,谁能给我解释一下输出的第五行吗?我不明白为什么MyClass对象b没有从func中分配返回对象c class MyClass { public: int x; std::string s; MyClass(const MyClass &other); MyClass(); void output(); }; MyClass::MyClass(const MyClass &other): x(2), s("s?") { } MyClass
MyClass
对象b
没有从func
中分配返回对象c
class MyClass
{
public:
int x;
std::string s;
MyClass(const MyClass &other);
MyClass();
void output();
};
MyClass::MyClass(const MyClass &other): x(2), s("s?") { }
MyClass::MyClass() : x(1), s("s1") { }
void MyClass::output() { cout << x << " " << s << endl; }
MyClass func(MyClass c) //MyClass c = Myclass(a)
{
cout << "2. in func: "; c.output();
c.s = "s2";
cout << "3. in func: "; c.output();
return c;
}
int main()
{
MyClass a;
cout << "1. "; a.output();
MyClass b = func(a);
cout << "4. "; a.output();
cout << "5. "; b.output();
}
我知道第1-4行是从哪里来的,但我不明白为什么最后,MyClass b.s
的值是s?
而不是s2
。是因为const
对象是在func
范围内创建的吗
编辑:
我知道当MyClass c
对象在func
范围内初始化时,会调用复制构造函数,但是返回的对象如何不分配给b
MyClass b = func(a);
该行将调用MyClass
的复制构造函数,从a
创建b
。尽管它有一个=
,但它不调用赋值运算符;对象尚未创建,因此没有可指定的对象
对象不需要是常量
就可以绑定到常量&
,即使是临时对象也可以绑定到它们
该行将调用MyClass
的复制构造函数,从a
创建b
。尽管它有一个=
,但它不调用赋值运算符;对象尚未创建,因此没有可指定的对象
对象不需要是
常量
就可以绑定到常量t&
,甚至临时变量也可以绑定到它们。在func中返回局部变量c。它得到复制构造,被复制到b中。您的复制构造函数指定s=“s?”因此它被设置为。在func中返回一个局部变量c。它得到复制构造,被复制到b中。您的复制构造函数指定了s=“s?”所以它被设置为
为什么我不能在这段代码中得到返回值优化
原因是函数正在返回c
,这是一个参数。即使它是一个值,因此是函数中的局部对象,但这是C++标准不允许的情况之一(在这种情况下,命名返回值优化或NRVO)。如果要创建c
的本地副本,则允许RVO:
MyClass func(MyClass c) //MyClass c = Myclass(a)
{
MyClass d = c;
cout << "2. in func: "; d.output();
d.s = "s2";
cout << "3. in func: "; d.output();
return d;
}
MyClass func(MyClass c)//MyClass c=MyClass(a)
{
MyClass d=c;
库特
为什么我不能在这段代码中得到返回值优化
原因是您的函数正在返回c
,这是一个参数。尽管它是一个值,因此是函数中的一个局部对象,但这是其中一种情况(在本例中,称为返回值优化,或NRVO)C++标准不允许。如果您要创建一个本地代码拷贝<代码> c>代码>,则允许RVO:
MyClass func(MyClass c) //MyClass c = Myclass(a)
{
MyClass d = c;
cout << "2. in func: "; d.output();
d.s = "s2";
cout << "3. in func: "; d.output();
return d;
}
MyClass func(MyClass c)//MyClass c=MyClass(a)
{
MyClass d=c;
难道它不是s2,因为MyClass b=func(a)
调用b
的复制构造函数,该构造函数将字符串成员初始化为s?
我认为您可能需要澄清为什么对输出感到惊讶。您的问题比您可能意识到的更微妙,并且没有一个答案能够理解。提示:可以选择另一个标题“为什么我不在这段代码中得到返回值优化?”@juanchopanza完成了,thanksit不是s2,因为MyClass b=func(a)
调用b
的复制构造函数,该构造函数将字符串成员初始化为s?
我认为您可能需要澄清为什么对输出感到惊讶。您的问题比您可能意识到的更微妙,并且没有一个答案能够理解。提示:另一个标题可以是“为什么我不能在这段代码中得到返回值优化?"@juanchopanza完成了,谢谢,由func
返回的对象会发生什么情况?@MaTi它在完整表达式的末尾被销毁。@Ma Ti它会被销毁,请尝试创建用户定义的析构函数以查看发生了什么。@PcAF我在析构函数和构造函数中添加了print语句,这有助于我理解tand发生了什么。那么,func
返回的对象发生了什么?@MaTi它在完整表达式的末尾被销毁。@如果它将被销毁,请尝试创建用户定义的析构函数以查看发生了什么。@PcAF我在析构函数和构造函数中添加了print语句,这有助于我理解它是什么发生。那么它在函数的开头和结尾得到了“复制构造”吗?是的。一次被传递给函数,一次被返回。那么它在函数的开头和结尾得到了“复制构造”吗?是的。一次被传递给函数,一次被返回。