微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 将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引用应该延长临时对象的生命周期.

代码生成UB输出.所以没有生命延伸.

为什么?我的意思是有人可以解释一下子发生什么事吗?

我的推理链在哪里出错?

FOO():

> A(32) – ctor
> return A(32) – 创建一个对本地对象的const引用并返回
> A a = foo(); – a由foo()返回值初始化,返回值超出范围(表达式外)并被销毁,但a已经初始化;

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

FOO_2():

> return 6 – 隐式创建A类型的临时对象,创建对该对象的const引用(延长其生命周期)并返回
> A a = foo(); – a由foo()返回值初始化,但a已经初始化;

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

解决方法

在语言规范中明确规定了每个特定上下文的临时生命周期扩展规则.而且它说

12.2 Temporary objects

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. […]

您的临时对象在函数退出时被销毁.这发生在收件人对象的初始化开始之前.

你似乎认为你的临时生活应该比这更长寿.显然,您正在尝试应用规则,该规则表明临时应该存在直到完整表达式结束.但该规则不适用于在函数内部创建的临时数.这种临时工的生命周期由他们自己的专门规则决定.

如果有人试图使用返回的引用,则foo和foo_2都会产生未定义的行为.

原文地址:https://www.jb51.cc/c/117430.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐