返回对本地对象的const引用时会发生什么? [英] What exactly happens when returning const reference to a local object?

查看:117
本文介绍了返回对本地对象的const引用时会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

struct A {
    A(int) : i(new int(783)) {
        std::cout << "a ctor" << std::endl;
    }

    A(const A& other) : i(new int(*(other.i))) {
        std::cout << "a copy ctor" << std::endl;
    }

    ~A() {
        std::cout << "a dtor" << std::endl;
        delete i;
    }

    void get() {
        std::cout << *i << std::endl;
    }

private:
    int* i;
};

const A& foo() {
    return A(32);
}

const A& foo_2() {
    return 6;
}

int main()
{
    A a = foo();
    a.get();
}

我知道,返回对本地值的引用是不好的。但是,另一方面,const引用应该延长对象的临时生存期。

I know, returning references to local values is bad. But, on the other hand, const reference should extend a temporary object lifetime.

此代码产生UB输出。所以没有寿命延长。

This code produce an UB output. So no life extention.

为什么?我是说有人可以逐步解释发生了什么事情?

Why? I mean can someone explain whats happening step by step?

我的推理链中哪里出了毛病?

Where is fault in my reasoning chain?

foo ():


  1. A(32)-ctor

  1. A(32) - ctor

返回A(32)-创建并返回对本地对象的const引用

return A(32) - a const reference to local object is created and is returned

A a = foo(); -a由foo()返回值初始化,返回值超出范围(表达式之外)并被销毁,但是a已被初始化;

A a = foo(); - a is initialized by foo() returned value, returned value goes out of scope(out of expression) and is destroyed, but a is already initialized;

(但实际上析构函数在复制构造函数之前被调用)

(But actually destructor is called before copy constructor)

foo_2():


  1. 返回6-类型A的临时对象被隐式创建,对该对象的const引用被创建(延长其寿命)并被返回

  1. return 6 - temp object of type A is created implicitly,a const reference to this object is created(extending its life) and is returned

A a = foo(); -a由foo()返回值初始化,返回值超出范围(表达式之外)并被销毁,但是a已被初始化;

A a = foo(); - a is initialized by foo() returned value, returned value goes out of scope(out of expression) and is destroyed, but a is already initialized;

(但实际上析构函数在复制构造函数之前被调用)

(But actually destructor is called before copy constructor)

推荐答案

语言规范中明确说明了每个特定的上下文。它说

Rules of temporary lifetime extension for each specific context are explicitly spelled out in the language specification. And it says that


12.2临时对象

5第二种情况是引用绑定到一个临时目录。 [...]函数返回语句
(6.6.3)中返回值的临时绑定一直存在,直到函数退出。 [...]

5 The second context is when a reference is bound to a temporary. [...] A temporary bound to the returned value in a function return statement (6.6.3) persists until the function exits. [...]

函数退出时,您的临时对象被破坏。这是在初始化接收方对象之前发生的。

Your temporary object is destroyed at the moment of function exit. That happens before the initialization of the recipient object begins.

您似乎以为临时对象的寿命应该比这更长。显然,您正在尝试应用规则,该规则要求临时对象可以保留到完整表达式的结尾。但是该规则不适用于在函数内部创建的临时对象。此类临时人员的生存时间受其自己专用的规则支配。

You seem to assume that your temporary should somehow live longer than that. Apparently you are trying to apply the rule that says that the temporary should survive until the end of the full expression. But that rule does not apply to temporaries created inside functions. Such temporaries' lifetimes are governed by their own, dedicated rules.

您的 foo 和您的 foo_2 如果有人尝试使用返回的引用,则会产生不确定的行为。

Both your foo and your foo_2 produce undefined behavior, if someone attempts to use the returned reference.

这篇关于返回对本地对象的const引用时会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆