如果我有一个class Foo
和一个原型为void bar(Foo* foo)
的方法。可以这样做:bar(&Foo());
?
我知道它编译和工作,但由于我对C ++比较陌生,我想知道创建的实例在使用后是否会被正确销毁,或者在做这个时我是否还要担心其他任何事情。
答案 0 :(得分:5)
这甚至不是有效的C ++。有些编译器可能很傻并接受它,但它们不应该这样做。你不能拿一个临时的地址。
此限制在C ++标准的第5.3.1节中给出:
一元
&
运算符的结果是指向它的指针 操作数。操作数应为左值或 qualified-id 。
Temporaries是prvalues,所以他们不能得到他们的地址。
现在,假设你的编译器接受了这个,那么指针在函数调用运行时有效,但在运行时只有。一旦它返回,临时被销毁,所以任何指向它的指针仍然存在(比如,如果函数存储它)是无效的。
答案 1 :(得分:2)
在一般情况下,它无效。 Foo()
是一个临时的,只要bar
返回就会死亡。 MSVC将错误地接受它作为扩展。
答案 2 :(得分:1)
您确定代码会编译吗?使用gcc,您将获得error: taking address of temporary
。
不应该(并且某些编译器不能)获取临时地址的原因是因为它超出了范围(因此被摧毁/解构)并且传递给bar
的地址不会是您有权访问的真实Foo
对象的地址。
答案 3 :(得分:1)
如果您使用的是本机C ++,则可以在MSVC2010中禁用语言扩展名。
项目 - >属性 - > C / C ++ - >语言 - >禁用语言扩展程序。
struct Foo
{
};
void bar(Foo* foo)
{
}
int main()
{
bar(&Foo());
}
输出
1> ------ Build build:项目:测试,配置:发布Win32 ------ 1 GT; TEST.CPP 1> Test.cpp(16):错误C2102:'&'需要l值 ==========构建:0成功,1个失败,0个最新,0个跳过==========
答案 4 :(得分:0)
好的..我只能看到一个原因..如果你必须在使用指针或本地之间做出决定,那么这将是一种(丑陋的)方法。 如果你想要一个本地人,那么你的电话会工作..如果你计划使用传入的一个,那么那也可以工作..
更合乎逻辑的方法是使用没有参数的函数覆盖。
void bar(){ Foo f; bar(&f);}
void bar(Foo * ifoo){...}
就我个人而言,我永远不会做你做过的事情......但这就是为什么它应该编译以及它为什么不应该。