你应该尽量不要使用new
, 因为使用它会带来内存管理的麻烦。
对于您的示例,只需执行以下操作:
int main(int, char*[])
{
SomeObject myObject;
// two phases
ParamClass foo(...);
myObject.myMethod(foo);
// one phase
myObject.myMethod(ParamClass(...));
return 0;
}
我推荐第一种方法(两次),因为第二种方法有一些微妙的问题。
编辑:评论并不适合描述我所指的陷阱。
如前所述@Fred Nurk
,该标准对临时人员的生命周期做了一些说明:
[类.临时]
(3) 临时对象被销毁作为评估完整表达式 (1.9) 的最后一步,该完整表达式 (从词法上) 包含它们被创建的点。即使评估以抛出异常结束也是如此。销毁临时对象的值计算和副作用仅与完整表达式相关联,与任何特定子表达式无关。
(5) 引用所绑定的临时对象或引用所绑定的子对象的完整对象的临时对象在引用的整个生命周期内都将持续存在 [注意:除了在某些情况下...]
(5) [例如...] 在函数调用 (5.2.2) 中对引用参数的临时绑定一直持续到包含该调用的完整表达式完成为止。
这可能导致两个细微的错误,大多数编译器都没有捕捉到:
Type const& bound_bug()
{
Type const& t = Type(); // binds Type() to t, lifetime extended to that of t
return t;
} // t is destroyed, we've returned a reference to an object that does not exist
Type const& forwarder(Type const& t) { return t; }
void full_expression_bug()
{
T const& screwed = forwarder(T()); // T() lifetime ends with `;`
screwed.method(); // we are using a reference to ????
}
Argyrios 应我的要求对 Clang 进行了修补,以便它检测到第一种情况(实际上还有一些我最初没有想到的情况)。forwarder
但是,如果实施不是内联的,则第二个可能很难评估。