我已经尝试谷歌这个问题,我找不到任何我认为相关的东西。所以我一定在寻找错误的东西;尽管如此,我还是很欣赏一些建议......
Foobar &foobar = *new Foobar(someArg, anotherArg);
只是我还是看起来很臭?
我理解new
关键字设计用于指针(如此):
Foobar *foobar = new Foobar(someArg, anotherArg);
但是,如果您不需要该实例上的指针,并且您想使用引用呢?或者,您是否需要显式初始化它(很像局部变量);如果是这种情况,如果我想用参数初始化怎么办?
以下不起作用(除非我做错了):
// the last argument is of type: int
Foobar &foobar(someArg, anotherArg);
...给出了编译错误:
初始化表达式列表被视为复合表达式 “Foobar&”类型的非const引用的无效初始化 来自临时的'int'类型
这似乎也不起作用:
Foobar &foobar = Foobar(someArg, anotherArg);
...给出了编译错误:
错误:类型的非const引用的初始化无效 'Foobar&'来自临时的'Foobar'
请记住我正在返回此值,因此我不想使用局部变量;我想在堆上使用一个值,而不是堆栈:
Foobar &helloWorld()
{
Foobar &foobar = *new Foobar(someArg, anotherArg);
foobar.HelloWorld();
return foobar;
}
我应该只使用指针,还是完全有效?
答案 0 :(得分:11)
为什么你认为你需要使用新的和引用?为什么不:
Foobar foobar(someArg, anotherArg);
对于你的函数 - 返回一个值:
Foobar helloWorld()
{
Foobar foobar(someArg, anotherArg);
foobar.HelloWorld();
return foobar;
}
或指针:
Foobar * helloWorld()
{
Foobar * foobar = new Foobar(someArg, anotherArg);
foobar->HelloWorld();
return foobar;
}
如果这样做 - 调用者负责在某个时刻删除分配的对象。
从非成员函数返回的地方通常不能合理地使用引用,因为您想要引用的内容通常不再存在。
答案 1 :(得分:5)
是的,那很臭!
如果你'新'某事,将其分配给指针(或智能指针类型),因为它需要再次删除以避免内存泄漏。引用通常不被认为是您需要再次删除的内容,因此如果其他人看到该代码(将新的对象分配给引用),它可能会使它们混淆。
你可以......
const Foobar &foobar = Foobar(someArg, anotherArg);
...如果你真的想要参考。请注意,一旦foobar超出范围,它引用的临时对象将会死亡。但是,当你可以直截了当地写下来时,写作并不是很重要:
Foobar foobar(someArg, anotherArg);
您可能实际上并不需要引用...它们通常(但不是唯一地)用于方法参数的类型。这样您就可以传递看起来像对象的东西,但只有指针的大小,并且方法可以修改。引用的引用主要是为了让你编写一个拷贝构造函数(我不会在这里解释!)。
答案 2 :(得分:3)
C ++中的引用实际上并不像人们期望的那样强大,我认为混淆来自习惯于Java和C#等语言的人,这些语言没有指针并且具有可以重新分配和使用的引用。
C ++中的引用通常最适合用作变量的别名,因此您可以简化参数传递和返回值等操作。在极少数情况下,您会尝试以第一行的方式获取引用。所以通常你不需要做你想做的事情:)
第二行当然是正确的,您可以从返回引用的函数中执行返回* foobar之类的操作。
答案 3 :(得分:2)
你写得对。但请记住,通过删除& refVar释放ptr是很奇怪的。 (它可能被误认为是不是由new创建的变量。)
你应该看看GotW是否有好的做法绕过http://www.gotw.ca/gotw/我不记得那是什么课程(还有一个以上)但是阅读它比任何人都意识到的更有价值(陷阱会少一些惊喜) )
你应该尝试编写永远不会使用指针的代码。我这样做但是当我需要一个BaseObj容器时卡住了。没有解决的问题。通常我使用STL容器并在堆栈上拥有大多数变量{MyClass myVar; ...}或作为成员并根据需要传递它。
一旦你开始传递引用而不是指针并使用stl容器而不是new,它很容易删除指针。请注意,我从不使用auto_ptr。矢量,字符串,双端队列,列表和地图应该完成你需要的大部分工作。还有其他容器。
答案 4 :(得分:1)
@Neil有一个观点,不过 - 从语法上来说,这就是你得到你想要的东西,但为什么你想要它呢?
答案 5 :(得分:1)
我建议使用智能指针。您需要管理所有权,并且引用不会为您执行此操作。实际上,它会使调用者难以理解任何所有权问题。正如Scott Langham在评论中提到的那样,std :: auto_ptr会起作用。使用Boost或TR1中的shared_ptr可能是个更好的主意。
boost::shared_ptr<Foobar> helloWorld()
{
boost::shared_ptr<Foobar> foobar(new Foobar(someArg, anotherArg));
foobar->HelloWorld();
return foobar;
}