You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为何std::queue执行pop()后,front()获取的值仍能存在?

为什么队列清空后局部变量的值还存在?

这问题问到点子上了,核心是搞明白引用的作用和值拷贝的区别,咱们结合你的代码一步步说:

先看你的代码片段:

int main() { 
    std::string val; 
    { 
        std::queue<std::string> q; 
        q.push("one"); 
        q.push("two"); 
        q.push("three"); 
        val = q.front(); 
        q.pop(); 
        q.pop(); 
        q.pop(); 
        std::cout << "is queue empty: " << boolalpha << q.empty() << '\n'; 
    } 
    std::cout << "val: " << val << '\n'; 
}

关键细节拆解:

  • q.front()确实返回队列首元素的引用,但你这里做的是val = q.front();——这是一个值拷贝操作。也就是说,你把队列里那个"one"字符串的内容,完完整整地复制到了val这个独立的std::string对象里。val和队列里的元素是两个完全分开的内存空间,互相不影响。
  • 之后的q.pop()操作,只会销毁队列里的元素(包括原来的"one"),但这和val半毛钱关系都没有——val已经拿到了自己的拷贝,它的生命周期是从main函数开始到结束,哪怕包含队列的那个大括号作用域结束、队列被销毁,val依然好好地活着,保存着之前拷贝的"one"

反过来想如果是引用会怎样?

要是你把val声明成引用:std::string& val = q.front();,那情况就完全不同了——val会变成队列首元素的别名,当你pop之后,原来的元素被销毁,val就成了悬空引用,再访问它就是未定义行为(可能输出乱码、崩溃,或者看似正常但实际上有隐患)。但你的代码里是值拷贝,所以完全安全。

总结一下:你存到局部变量的不是引用本身,而是引用指向的值的拷贝,所以队列的销毁不会影响这个局部变量~

内容的提问来源于stack exchange,提问作者r18ul

火山引擎 最新活动