当返回值绑定到调用函数中的 const 引用时,它的生命周期如何扩展到调用函数的范围?

2024-03-25

“如果从函数返回一个值(而不是引用),然后将其绑定到调用函数中的 const 引用,则其生命周期将扩展到调用函数的范围。”

所以:情况A

const BoundingBox Player::GetBoundingBox(void)
{
    return BoundingBox( &GetBoundingSphere() );
}

返回类型的值const BoundingBox从函数GetBoundingBox()

变体 I:(将其绑定到 const 引用)

const BoundingBox& l_Bbox = l_pPlayer->GetBoundingBox();

变体 II:(将其绑定到 const 副本)

const BoundingBox l_Bbox = l_pPlayer->GetBoundingBox();

两者都工作正常,但我没有看到l_Bbox对象超出范围。 (不过,据我了解,在变体一中,不会调用复制构造函数,因此比变体二稍好一些)。

另外,为了进行比较,我做了以下更改。

CASE B

BoundingBox Player::GetBoundingBox(void)
{
    return BoundingBox( &GetBoundingSphere() );
}

与变体: 我

BoundingBox& l_Bbox = l_pPlayer->GetBoundingBox();

and II:

BoundingBox l_Bbox = l_pPlayer->GetBoundingBox();

物体l_Bbox仍然没有走出范围。 “将其绑定到调用函数中的 const 引用,其生存期将扩展到调用函数的范围”,如何真正将对象的生存期扩展到调用函数的范围?

我在这里错过了一些琐碎的事情吗?


通常,临时对象(例如函数调用返回的对象)的生命周期可以延伸到“封闭表达式”的末尾。但是,临时绑定到引用的生命周期通常会“提升”到引用的生命周期(可能是也可能不是调用函数的生命周期),但有一些例外。 12.2/5“临时对象”中的标准涵盖了这一点:

引用所绑定的临时对象或临时对象(临时对象所绑定的子对象的完整对象)在引用的生命周期内持续存在,除非下面指定。构造函数构造函数初始化程序 (12.6.2) 中引用成员的临时绑定将持续存在,直到构造函数退出。函数调用 (5.2.2) 中对引用参数的临时绑定将持续存在,直到包含调用的完整表达式完成为止。

请参阅以下内容了解更多信息:

  • C++ 常量引用生命周期(容器适配器) https://stackoverflow.com/questions/2604206/c-constant-reference-lifetime/2604269#2604269
  • GotW #88:“最重要的常量”的候选人 http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/

一个可能有助于直观地了解正在发生的事情的示例:

#include <iostream>
#include <string>

class foo {
public:
    foo( std::string const& n) : name(n) { 
        std::cout << "foo ctor - " << name + " created\n"; 
    };
    foo( foo const& other) : name( other.name + " copy") { 
        std::cout << "foo copy ctor - " << name + " created\n";
    };

    ~foo() { 
        std::cout << name + " destroyed\n"; 
    };

    std::string getname() const { return name; };
    foo getcopy() const { return foo( *this); };

private:
    std::string name;
};

std::ostream& operator<<( std::ostream& strm, foo const& f) {
    strm << f.getname();
    return strm;
}


int main()
{
    foo x( "x");

    std::cout << x.getcopy() << std::endl;

    std::cout << "note that the temp has already been destroyed\n\n\n";

    foo const& ref( x.getcopy());

    std::cout << ref << std::endl;

    std::cout << "the temp won't be deleted until after this...\n\n";
    std::cout << "note that the temp has *not* been destroyed yet...\n\n";
}

其中显示:

foo ctor - x created
foo copy ctor - x copy created
x copy
x copy destroyed
note that the temp has already been destroyed


foo copy ctor - x copy created
x copy
the temp won't be deleted until after this...

note that the temp has *not* been destroyed yet...

x copy destroyed
x destroyed
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当返回值绑定到调用函数中的 const 引用时,它的生命周期如何扩展到调用函数的范围? 的相关文章

  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐