为什么在const&中使用在赋值分配器中调用,但赋值是正确的

时间:2012-08-01 15:12:04

标签: c++ callstack

  

可能重复:
  How to return member that can be changed?

我知道如果我在const& amp;在赋值(和被调用的方法签名)中,比引用对象的生命周期延长到方法结束。

Employee const& getEmp(int a) {
    return Employee(a);
}
Employee const& tmpEmp = m.getEmp(10);  //
... stuff 
//end of scope - tmpEmp valid until here

我写了很少的程序,看到它按预期工作。 我的问题不是如何做到这一点? 我的问题是关于编译器如何做到这一点? 正如您从示例中看到的,析构函数在返回后立即被调用,所以我想知道析构函数是如何调用的,但是在调用析构函数之后tmpEmp是有效的吗?

#include <iostream>
using namespace std;

class Employee {
public:
    Employee() : a(0){
        cout << "c-emp" << a << endl;
    }
    Employee(const Employee& newE) {
        a = newE.a;
        cout << "c-c-emp" << a << endl;
    }
    Employee(int a) : a(a) {
        cout << "c-emp" << a << endl;
    }
    ~Employee() {
        cout << "d-emp" << a << endl;
    }
    int a;
};
class Manager {
public:
    Manager() {}
    ~Manager() {}
    Employee const& getEmp(int a) {
        return Employee(a);
    }
};

int main(int argc, char **argv) {
    Manager m;
    Employee const& tmpEmp = m.getEmp(10);
    cout << "tmpEmp " << tmpEmp.a <<endl;
}

output:
c-emp10
d-emp10   - destructor is called and tmpEmp is still valid? how is that?
tmpEmp 10

2 个答案:

答案 0 :(得分:3)

你的代码错了。您将返回对本地对象的引用,并且本地对象不符合您了解的生命周期扩展的条件。在您有机会将返回值分配给另一个变量之前,本地对象的生命周期结束,因此无法延长其生命周期。

生命周期扩展适用于临时对象:

Employee getEmp(int a) {
    return Employee(a);
}
Employee const& tmpEmp = m.getEmp(10);  //
... stuff 
//end of scope - tmpEmp valid until here

现在,getEmp()返回一个临时对象(不是对本地对象的引用),并且该对象在赋值发生时仍然有效。所以它的寿命会延长。

答案 1 :(得分:3)

你错了。

首先,赋值 never 对对象的生命周期有任何影响。 它只是一个副作用的运算符。

其次,如果使用a初始化(不分配)const引用 临时的,临时的生命周期延长到匹配 参考的生命周期。但是也有例外。 (而且我已经 从来没有找到任何实用的功能。)

用作返回值的const引用是其中一个例外(for 它不可实现的简单原因)。初始化退货 具有临时的const引用类型延长了生命周期 暂时的。

最后,即使它确实如此,在你的情况下它也无济于事,因为 由临时初始化的参考不再存在 在调用函数的完整表达式之后。