C++获取临时对象的地址[复制]

sqxo8psd  于 2023-06-07  发布在  其他
关注(0)|答案(3)|浏览(185)

此问题已在此处有答案

Taking the address of a temporary object(7个回答)
8年前关闭。
我有两个代码段,我希望得到相同的结果:
第一个:

SomeClass somefunc(...){
    SomeClass newObj;
    //some codes modify this object
    return newObj;
}

int main(){
    SomeClass *p;
    p = &(somefuc(...));
}

第二个:

SomeClass *somefunc(...){
    SomeClass newObj;
    //some codes modify this object
    return &newObj;
}

int main(){
    SomeClass *p;
    p = somefunc(...);
}

为什么当我尝试构建第一个代码段时,我得到了一个“获取临时对象的地址”错误,而第二个代码段却没有产生错误?

3htmauhk

3htmauhk1#

在你考虑这个问题之前,你需要学习暂时生活的规则。
广义的情况是临时对象在创建它的全表达式结束时被销毁。言下之意是如果

SomeClass *p;
p = &(somefunc(...));

如果p被允许工作,那么p将是一个悬空指针,指向一个不再存在的对象。
上述规则的一个很大的例外是,当一个具有自动生存期的引用被直接绑定到临时对象时,临时对象的生存期被延长为等于引用的生存期。请注意,这并不包括const T& make_lvalue(const T& t) { return t; },因为引用不是直接绑定的,也不是类成员引用。
有几种情况是完全安全的,其中临时地址仅立即使用,而不是存储供以后使用。例如

memcpy(buffer, &f(), sizeof(decltype(f())));

当然,这会导致您遇到的“临时地址”错误,但在C++11和C ++14中,您可以通过

memcpy(buffer, std::addressof(f()), sizeof(decltype(f())));

但不要存储结果指针。

of1yzvn4

of1yzvn42#

第一个代码片段没有正确地编译,因为,正如编译器所说,你不能接受一个临时对象的地址,因为它会在表达式的结尾被销毁(这里:分配)。因此,保存其地址将是毫无意义的。
第二个代码片段确实编译了,但仍然是不正确的,尽管它似乎可以工作,原因是here(至少如果你试图通过指针访问对象)。

j7dteeu8

j7dteeu83#

第一个示例无法编译,因为somefunc返回了一个值,而您试图获取它返回的这个临时对象的地址。这将工作:

Someclass* p;
Someclass  val = somefunc (...);
p = &val;

第二个例子没有编译--或者说不应该编译--因为somefunc应该返回一个Someclass,但是它返回了一个指向Someclass的指针。使它返回Someclass*,然后它应该编译-但现在您返回的是一个指向局部变量的指针,该变量在您离开函数后不再存在。最好的解决方案是第一个例子,在这里修补。

相关问题