[英]Returning an object from a function in C++: its process and nature
我很困惑从函数返回对象。 例如:
class A
{
public:
~A(){}
};
A find()
{
...
A a;
return a;
}
它通过引用还是按值返回“ a”? 此外,“查找”是否先删除“ a”,然后返回还是先返回,然后删除“ a”?
在您的函数中,您正在返回一个值,而不是引用。
A find();
返回类型为A
是为值,副本a
会回来。
为了返回引用,您应按以下方式编写函数。
A& find();
返回类型A&
表示对A的引用。但是应相应更改函数主体,以返回有效的引用。
使用当前的实现,您正在函数内部创建对象a
。 因此,在函数执行结束时,超出范围时会被删除。
您的问题“而且,“查找”是先删除“ a”,然后返回还是先返回,然后删除“ a”?”
将首先返回a
副本,然后将a
删除。
如果返回引用,则将返回引用,然后删除对象a
。
在此代码中,您按值返回,这就是返回值优化( RVO )发挥作用的地方。 创建“ a”的副本,然后删除原始的“ a”,返回“ a”的副本。 不确定正确的顺序。
A find()
{
...
A a;
return a;
}
按值返回。
技术上的副本a
构造, a
被破坏,则返回副本。 我在C ++标准中找不到任何可以指定这些操作特定顺序的内容,但是在逻辑上是隐含的。 显然,销毁后无法复制。
我怀疑这没有被指定为允许C ++实现支持各种各样的调用约定 。
注意:这意味着返回的对象必须是可复制的。 如果复制构造函数被删除或不可访问,则无法按值返回。
没有办法确定是首先返回还是销毁。 没关系,如果要在哪里设计程序,请摇头。
但是,在实践中,现代的优化编译器将尽一切力量避免使用“ 返回值优化”的统称使用各种方法进行复制和销毁。
请注意,在极少数情况下,允许违反“ 假设规则” 。 通过跳过副本的构建和销毁,可能不会发生某些副作用。
还要注意,即使消除了复制的需要,该对象也必须是可复制的。
A & find()
{
...
A a;
return a;
}
将返回参考,但这是一个非常糟糕的主意。 a
具有该功能范围的自动存储期限,将在返回时销毁。 这就给调用者留下了悬挂的引用 ,即对不再存在的变量的引用。
为了解决这个问题,
std::unique_ptr<A> find()
{
...
auto a = std::make_unique<A>();
return a;
}
但是您会发现,使用现代编译器,这并不比大多数情况下按值返回更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.