本文介绍了为什么临时的生存期不会延长到包含对象的生命周期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道临时不能绑定到非const引用,但可以绑定到const引用。也就是

I know that a temporary cannot be bound to a non-const reference, but it can be bound to const reference. That is,

 A & x = A(); //error
 const A & y = A(); //ok

我也知道在第二种情况out A()扩展到const引用的生命周期(即 y )。

I also know that in the second case (above), the lifetime of the temporary created out of A() extends till the lifetime of const reference (i.e y).

但我的问题是:

绑定到临时的const引用可以进一步 >绑定到另一个const引用,将临时生命周期延长到第二个对象的生命周期?

我试过这个,但没有工作。我不太明白这一点。我写了这段代码:

I tried this and it didn't work. I don't exactly understand this. I wrote this code:

struct A
{
   A()  { std::cout << " A()" << std::endl; }
   ~A() { std::cout << "~A()" << std::endl; }
};

struct B
{
   const A & a;
   B(const A & a) : a(a) { std::cout << " B()" << std::endl; }
   ~B() { std::cout << "~B()" << std::endl; }
};

int main() 
{
        {
            A a;
            B b(a);
        }
        std::cout << "-----" << std::endl;
        {
            B b((A())); //extra braces are needed!
        }
}

输出():

 A()
 B()
~B()
~A()
-----
 A()
 B()
~A()
~B()

为什么临时对象 A()在第二种情况下在对象 b 之前被销毁?标准(C ++ 03)是否讨论这种行为?

Difference in output? Why the temporary object A() is destructed before the object b in the second case? Does the Standard (C++03) talks about this behavior?

推荐答案

标准考虑了两种情况,临时扩展:

The standard considers two circumstances under which the lifetime of a temporary is extended:

§12.2/ 5第二个上下文是当引用绑定到临时的时候。 [...]

§12.2/5 The second context is when a reference is bound to a temporary. [...]

这两个都不允许您通过稍后将引用绑定到另一个来延长临时的生命周期const引用。但是忽略这种偏见,想想发生了什么:

None of those two allow you to extend the lifetime of the temporary by a later binding of the reference to another const reference. But ignore the standarese and think of what is going on:

暂时在栈中创建。从技术上讲,调用约定可能意味着一个返回值(临时)适合寄存器可能甚至不能在堆栈中创建,但是忍受我。当您将常量引用绑定到临时时,编译器在语义上创建一个隐藏的命名变量(这就是为什么复制构造函数需要可访问,即使它不被调用),并将引用绑定到该变量。无论复制是实际制作还是省略都是一个细节:我们有一个未命名的局部变量和对它的引用。

Temporaries are created in the stack. Well, technically, the calling convention might mean that a returned value (temporary) that fits in the registers might not even be created in the stack, but bear with me. When you bind a constant reference to a temporary the compiler semantically creates a hidden named variable (that is why the copy constructor needs to be accessible, even if it is not called) and binds the reference to that variable. Whether the copy is actually made or elided is a detail: what we have is an unnamed local variable and a reference to it.

标准允许你的用例,那么这意味着临时的生命周期必须被一直扩展,直到最后一个对该变量的引用。现在考虑你的例子的这个简单的扩展:

If the standard allowed your use case, then it would mean that the lifetime of the temporary would have to be extended all the way until the last reference to that variable. Now consider this simple extension of your example:

B* f() {
   B * bp = new B(A());
   return b;
}
void test() {
   B* p = f();
   delete p;
}

现在的问题是临时的(让它调用 _T )绑定在 f()中,它的行为就像一个局部变量。引用绑定在 * bp 内。现在对象的生命周期超出了创建临时的函数,但是因为 _T 没有被动态分配是不可能的。

Now the problem is that the temporary (lets call it _T) is bound in f(), it behaves like a local variable there. The reference is bound inside *bp. Now that object's lifetime extends beyond the function that created the temporary, but because _T was not dynamically allocated that is impossible.

您可以尝试并推理在此示例中延长临时文件生命周期所需的努力,答案是如果没有某种形式的GC,则无法完成。

You can try and reason the effort that would be required to extend the lifetime of the temporary in this example, and the answer is that it cannot be done without some form of GC.

这篇关于为什么临时的生存期不会延长到包含对象的生命周期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 08:30