引用可以延长由 mamber 函数返回的 class 的任何成员数据的生命周期吗
Can a reference prolong the lifetime of any member data of a class which is returned by a mamber function
class sample
{
std::string mString;
public:
void Set(const std::string &s)
{
mString = s;
}
//std::string Get() const
const std::string& Get() const
{
return mString;
}
};
假设我有一个如上所述的 class,现在我这样使用 class:
sample *p = new sample;
p->Set("abcdefg");
const std::string& ref = p->Get();
delete p;
p = nullptr;
std::cout << ref << std::endl;
如你所见,成员函数Get
returns一个引用,它赋给了外部引用ref
。之后,整个对象被删除。
不过,这段代码似乎没有任何错误。
我有点困惑。它可能 运行 只是因为我很幸运,或者它的引用 ref
延长了成员变量的生命周期 mString
?
否,通过引用绑定延长生命周期仅适用于从纯右值具体化的临时对象。
使用 new
创建的对象的生命周期永远不会超过 delete
。
您在这里看到的只是未定义行为的表现。 ref
在 delete p;
之后悬空,因此在 cout
语句中读取它具有未定义的行为。
如果 Get
是 returning by-value (std::string Get() const
),那么临时从函数的生命周期将延长至引用 ref
.
的生命周期
在这种情况下,程序行为将是 well-defined。
同样,如果 sample
对象具有自动存储持续时间,则引用不会延长其生命周期或其子对象之一的生命周期:
/* DO NOT USE: Undefined behavior */
const std::string& ref = []() -> const std::string& {
sample s;
p.Set("abcdefg");
return s->Get();
// lifetime of s ends with function returning
}();
/* UNDEFINED BEHAVIOR */
std::cout << ref << std::endl;
这是 lambda 的 return 类型,需要将其从 const std::string&
更改为 std::string
以避免 UB。只有第一个引用绑定可以延长生命周期,因此在这种情况下更改 Get
的 return 类型是不够的。
class sample
{
std::string mString;
public:
void Set(const std::string &s)
{
mString = s;
}
//std::string Get() const
const std::string& Get() const
{
return mString;
}
};
假设我有一个如上所述的 class,现在我这样使用 class:
sample *p = new sample;
p->Set("abcdefg");
const std::string& ref = p->Get();
delete p;
p = nullptr;
std::cout << ref << std::endl;
如你所见,成员函数Get
returns一个引用,它赋给了外部引用ref
。之后,整个对象被删除。
不过,这段代码似乎没有任何错误。
我有点困惑。它可能 运行 只是因为我很幸运,或者它的引用 ref
延长了成员变量的生命周期 mString
?
否,通过引用绑定延长生命周期仅适用于从纯右值具体化的临时对象。
使用 new
创建的对象的生命周期永远不会超过 delete
。
您在这里看到的只是未定义行为的表现。 ref
在 delete p;
之后悬空,因此在 cout
语句中读取它具有未定义的行为。
如果 Get
是 returning by-value (std::string Get() const
),那么临时从函数的生命周期将延长至引用 ref
.
在这种情况下,程序行为将是 well-defined。
同样,如果 sample
对象具有自动存储持续时间,则引用不会延长其生命周期或其子对象之一的生命周期:
/* DO NOT USE: Undefined behavior */
const std::string& ref = []() -> const std::string& {
sample s;
p.Set("abcdefg");
return s->Get();
// lifetime of s ends with function returning
}();
/* UNDEFINED BEHAVIOR */
std::cout << ref << std::endl;
这是 lambda 的 return 类型,需要将其从 const std::string&
更改为 std::string
以避免 UB。只有第一个引用绑定可以延长生命周期,因此在这种情况下更改 Get
的 return 类型是不够的。