IE盒子

搜索
查看: 110|回复: 1

C++的那些事——临时变量的生存期延长

[复制链接]

2

主题

7

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2022-12-24 11:49:14 | 显示全部楼层 |阅读模式
C++的那些事——临时量生存期延长的坑
提问环节

开始之前,先进入提问环节,看下面的代码是否存在问题?
代码一:
int&& GetObj() {
    int a;
    return std::move(a);
}

auto ref = GetObj();
代码二:
int&& GetObj(const int& a) {
    return std::move(a);
}
auto ref = GetObj(10);
代码三:
struct A {
    int& a;
};

auto ptr = new A(10);
int b = ptr->a;   // 使用变量a
代码四:
struct A {
    int& a;
};
A obj1{ 10 };
A obj2(20);   // C++20起,允许圆括号的初始化
正式介绍

在C++中,存在这么一条法则:引用一旦绑定到临时变量上,则临时变量的生成期会被延长到引用的生存期
这里说的引用不区别是左值引用还是右值引用。  什么意思呢?举例说明:
const int& a = 10;    // 字面值10的生命周期被延长到与引用变量a相同。

class A {
public:
    A() {
        cout << "construct" << enld;
    }
    ~A() {
        cout << "destruct" << endl;
    }
}

A&& ref = A();   // 创建了一个临时对象A, 此时它的生命期被延长的与ref变量生存期相同。
上面的概念很好理解,但是要注意它的核心原则是:  临时量的生存期的延长只与它直接绑定的引用变量相关联,如果使用绑定了该临时量的引用初始化的第二引用时,第二个引用生命周期不会不影响临时量的生存期,不存在传递性。
正因为上面的原因,下面的几个场景会导致产生悬挂引用的风险,代码BUG很难定位,对于刚入门的开发同事,是一个天坑:

  • return 语句中绑定到函数返回值的临时量不被延续:它立即于返回表达式的末尾销毁。这种函数始终返回悬垂引用。
  • 在函数调用中绑定到函数形参的临时量,存在到含这次函数调用的全表达式结尾为止:若函数返回一个引用,而其生命长于全表达式,则它将成为悬垂引用。
  • 绑定到 new 表达式中所用的初始化器中的引用的临时量,存在到含该 new 表达式的全表达式结尾为止,而非被初始化对象的存在期间。若被初始化对象的声明长于全表达式,则其引用成员将成为悬垂引用。
  • 绑定到用直接初始化语法(括号),而非列表初始化语法(花括号)初始化的聚合体的引用元素中的引用的临时量,存在直至含该初始化器的全表达式末尾为止。
而文章开头举的四个例子,正好对应了上面的四种场景。
揭晓答案

代码一:
int&& GetObj() {
    int a;
    return std::move(a);
}
auto ref = GetObj();
答案: 存在问题,返回局部变量的引用,悬挂引用。

....
接下来,剩余的内容去视频中继续看。。 (兄弟们实在对不住了,我B站UP主视频播放量太少了,经常个位数,靠兄弟们涨点人气,只能麻烦兄弟们过去给点个赞,投个币啥的)
回复

使用道具 举报

2

主题

10

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 前天 20:56 | 显示全部楼层
支持,楼下的跟上哈~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表