我有两个代码段,我期望相同的结果:
第一个:
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(...);
}
当我尝试构建第一个代码段时,为什么我会得到"临时对象的地址"错误,而第二代码段未产生错误?
甚至在考虑此事之前,您需要学习临时寿命的规则。
广泛的情况是,临时对象在创建它的全表达结束时被破坏。这意味着如果
SomeClass *p;
p = &(somefunc(...));
被允许工作,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())));
但不要存储生成的指针。
第一个摘要确实不编译,因为正如编译器所说,您无法在表达式结束时销毁临时对象的地址(此处:作业:作业)。因此,保存其地址将毫无意义。
第二个片段确实编译了,但仍然不正确,尽管出于此处所述的原因,它似乎有效(至少如果您尝试通过指针访问对象)。
>第一个示例没有编译,因为某些func返回一个值,并且您尝试获取它返回的临时事物的地址。这将有效:
Someclass* p;
Someclass val = somefunc (...);
p = &val;
第二个示例不编译 - 或不应该 - 因为某些人应该返回someClass,而是将指针返回到躯体阶层。使其返回someClass*,然后应该编译 - 但是现在您正在将指针返回到局部变量,该变量不再存在后,该变量不再存在。最好的解决方案是第一个示例,如此处修补。