繁体   English   中英

从C ++中的函数返回对象:其过程和性质

[英]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”?

A find()
{
    ...
    A a;
    return a; 
}

按值返回。

困难的部分: 此外,“查找”是否先删除“ a”,然后返回还是先返回,然后删除“ 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM