繁体   English   中英

我是否正确初始化了我的C ++引用变量?

[英]Am I initializing my C++ reference variables correctly?

我试过谷歌这个问题,我找不到任何我认为相关的东西。 所以我一定在寻找错误的东西; 尽管如此,我还是很欣赏一些建议......

Foobar &foobar = *new Foobar(someArg, anotherArg);

它只是我还是看起来很臭?

我知道new关键字设计用于指针(如此):

Foobar *foobar = new Foobar(someArg, anotherArg);

但是,如果您不需要该实例上的指针,并且您想使用引用呢? 或者,您是否需要显式初始化它(很像局部变量); 如果是这种情况,如果我想用参数初始化怎么办?

以下不起作用(除非我做错了):

// the last argument is of type: int
Foobar &foobar(someArg, anotherArg);

...给出编译器错误:

初始化表达式列表作为复合表达式处理从'int'类型的临时表中无效初始化类型'Foobar&'的非const引用

而且这似乎不起作用:

Foobar &foobar = Foobar(someArg, anotherArg);

...给出编译器错误:

错误:从'Foobar'类型的临时类型'Foobar&'类型的非const引用无效初始化

更新1:

请记住我正在返回此值,因此我不想使用局部变量; 我想在堆上使用一个值,而不是堆栈:

Foobar &helloWorld()
{
    Foobar &foobar = *new Foobar(someArg, anotherArg);
    foobar.HelloWorld();
    return foobar;
}

我应该只使用指针,还是完全有效?

为什么你认为你需要使用新的和引用? 为什么不:

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;
}

如果这样做 - 调用者负责在某个时刻删除分配的对象。

从非成员函数返回的地方通常不能合理地使用引用,因为您想要引用的内容通常不再存在。

是的,那很臭!

如果你是'new'的东西,请将它指定给指针(或智能指针类型),因为它需要再次删除以避免内存泄漏。 引用通常不被认为是您需要再次删除的内容,因此如果其他人看到该代码(将新的对象分配给引用),它可能会混淆它们。

你可以做...

const Foobar &foobar = Foobar(someArg, anotherArg);

...如果你真的想要一个参考。 请注意,一旦foobar超出范围,它引用的临时对象将会死亡。 但是,当你可以直截了当地写下时,写作中没有太多意义:

Foobar foobar(someArg, anotherArg);

您可能实际上并不需要引用...它们通常(但不是唯一地)用于方法参数的类型。 这样您就可以传递看起来像对象的东西,但只有指针的大小,并且方法可以修改。 引用的引用主要是为了让你编写一个拷贝构造函数(我不会在这里解释!)。

C ++中的引用实际上并不像人们期望的那样强大,我认为混淆来自习惯于Java和C#之类的语言的人,这些语言没有指针并且具有可以重新分配和使用的引用。

C ++中的引用通常最适合用作变量的别名,因此您可以简化参数传递和返回值等操作。 在极少数情况下,您会尝试以第一行的方式获取引用。 所以通常你不需要做你想做的事:)

第二行当然是正确的,你可以从返回引用的函数中执行返回* foobar之类的操作。

你写得对。 但请记住,通过删除&refVar释放ptr是很奇怪的; (它可能被误认为是不是由new创建的变量)。

你应该看看GotW是否有好的做法绕过http://www.gotw.ca/gotw/我不记得那是什么课(当时还有一个以上)但是通过阅读更有价值然后任何人意识到(陷阱将是少惊一觉)

你应该尝试编写永远不会使用指针的代码。 我这样做但是当我需要一个BaseObj容器时卡住了。 没有解决的问题。 通常我使用STL容器并在堆栈上拥有大多数变量{MyClass myVar; ...}或作为成员并根据需要传递它。

一旦你开始传递引用而不是指针并使用stl容器而不是new,它很容易删除指针。 请注意,我从不使用auto_ptr。 矢量,字符串,双端队列,列表和地图应该完成你需要的大部分工作。 还有其他容器。

不,你已经明白了。 一个foo&“指向”实际的对象,所以如果你真的想要一个foo引用,你必须取消引用foo指针。

虽然@Neil有一点意义 - 从语法上讲,这就是你得到你想要的东西,但你为什么要这样做呢?

我建议使用智能指针。 您需要管理所有权,并且引用不会为您执行此操作。 实际上,它会使调用者难以理解任何所有权问题。 正如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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM