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

bra*_*ter 9 c++ memory const pass-by-reference

"如果从函数返回一个值(不是引用),那么将它绑定到调用函数中的const引用,它的生命周期将扩展到调用函数的范围."

所以:案例A.

const BoundingBox Player::GetBoundingBox(void)
{
    return BoundingBox( &GetBoundingSphere() );
}
Run Code Online (Sandbox Code Playgroud)

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

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

const BoundingBox& l_Bbox = l_pPlayer->GetBoundingBox();
Run Code Online (Sandbox Code Playgroud)

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

const BoundingBox l_Bbox = l_pPlayer->GetBoundingBox();
Run Code Online (Sandbox Code Playgroud)

两者都工作正常,我没有看到l_Bbox对象超出范围.(虽然,我在变体1中理解,复制构造函数未被调用,因此稍微好于变体II).

另外,为了比较,我做了以下更改.

案例B

BoundingBox Player::GetBoundingBox(void)
{
    return BoundingBox( &GetBoundingSphere() );
}
Run Code Online (Sandbox Code Playgroud)

与变体:我

BoundingBox& l_Bbox = l_pPlayer->GetBoundingBox();
Run Code Online (Sandbox Code Playgroud)

和II:

BoundingBox l_Bbox = l_pPlayer->GetBoundingBox();
Run Code Online (Sandbox Code Playgroud)

该对象l_Bbox仍然没有超出范围.如何"将它绑定到调用函数中的const引用,它的生命周期将扩展到调用函数的范围",真正将对象的生命周期延长到调用函数的范围?

我在这里错过了一些小事吗?

Mic*_*urr 9

通常,临时对象(例如函数调用返回的对象)的生命周期延伸到"封闭表达式"的末尾.但是,对引用的临时绑定通常会将其生命周期"提升"到引用的生命周期(可能是也可能不是调用函数的生命周期),但有一些例外情况.这包含在12.2/5"临时对象"中的标准中:

除了下面指定的内容之外,引用绑定的临时对象或作为临时绑定对象的子对象的完整对象的临时对象的生命周期仍然存在.绑定到构造函数的ctor-initializer(12.6.2)中的引用成员的临时绑定将持续存在,直到构造函数退出.在函数调用(5.2.2)中与引用参数的临时绑定将持续存在,直到包含该调用的完整表达式完成为止.

有关更多信息,请参阅以下内容

一个可能有助于可视化正在发生的事情的示例:

#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";
}
Run Code Online (Sandbox Code Playgroud)

哪个显示:

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
Run Code Online (Sandbox Code Playgroud)


AnT*_*AnT 5

首先,临时对象的生命周期被延长到绑定到它的 const 引用的生命周期,而不是“调用函数的范围”(尽管也许这就是您所说的奇怪措辞“调用函数的范围”的意思) 。这就是您所CASE A说明的,您将const引用附加到临时变量。只要引用存在,临时对象就会继续存在。当引用结束其生命周期时,临时对象也会被销毁。

其次,你的CASE B格式根本不正确,不可编译。即,

BoundingBox& l_Bbox = l_pPlayer->GetBoundingBox(); 
Run Code Online (Sandbox Code Playgroud)

是非法的。在 C++ 中将非常量引用附加到临时变量是非法的。如果你的编译器允许,那么它一定是你的编译器的一个怪癖/扩展,这与 C++ 语言无关。