【发布时间】:2018-07-24 18:11:07
【问题描述】:
考虑以下代码。当 doStuff() 被调用但没有使用返回值时会发生什么? SomeClass 是否仍然创建?当然,创建本身可能会产生重要的副作用,但是复制构造函数也可以,并且它们在 RVO / 复制省略中仍然被省略。
SomeClass doStuff(){
//...do stuff
return SomeClass( /**/);
}
SomeClass some_object = doStuff();
doStuff(); //What happens here?
(编辑:用 GCC -O3 对此进行了测试。对象被构造然后立即销毁)
【问题讨论】:
-
函数返回的对象在超出范围之前将保持有效。这意味着调用函数的封闭范围,然后它超出范围将调用任何对象析构函数。在您的示例中,您没有为第二次调用分配任何内容,但同样适用。
-
@SPlatten 这不是真的。在示例中,为
some_class调用了复制构造函数,但 RVO 除外。返回的对象遵循相同的规则,因为它是一个临时对象,并且会在语句之后立即销毁 -
我会这样看:假设该函数位于已编译的第三方库中。一旦在客户端代码中调用,编译器如何提前知道返回的对象是否会被忽略?现在,根据定义是否可访问,让函数表现不同是否是可取的/明智的?好吧,这并不能真正回答你的问题,但我认为这对标准中的决定提供了很大的暗示。
-
我会说它有点像
{SomeClass s{};}(构造函数和析构函数必须被调用(至少好像)) -
@PasserBy,对象的范围和生命周期规则适用于复制或以其他方式复制的所有对象。如果对象不是全局的并且是在范围内创建的,那么它将在超出范围时被销毁(它的析构函数)。