2

可能重复:
如何返回可以更改的成员?

我了解到,如果我在分配(以及被调用的方法签名)中使用 const& ,则被引用对象的生命周期会延长到方法结束。

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
4

2 回答 2

3

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

生命周期延长适用于临时对象:

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

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

于 2012-08-01T15:17:47.773 回答
3

你学错了。

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

Second, if you initialize (not assign) a const reference with a temporary, the lifetime of the temporary is extended to match the lifetime of the reference. There are exceptions, however. (And I've never found any pratical use for this feature.)

A const reference used as a return value is one of the exceptions (for the simple reason that it's not implementable). Initializing a return of a const reference type with a temporary does not extend the life of the temporary.

And finally, even if it did, it wouldn't help you in your case, because the reference which was initialized by the temporary ceases to exist after the full expression which invokes the function.

于 2012-08-01T15:20:04.457 回答