c++ 引用向量的问题?

Posted

技术标签:

【中文标题】c++ 引用向量的问题?【英文标题】:c++ reference to a vector issues? 【发布时间】:2011-06-20 03:06:32 【问题描述】:

在将向量的引用作为参数传递时我遇到了一些困难。最初它是一个指向指针向量的指针,被调用的函数会改变调用它的任何对象的属性。比如我用过:

(*myVector)[i]->myFunction();

一切都很完美。 myFunction() 将转换作为 myVector 的当前索引的任何对象。

现在我改变了向量来保存一组对象,而不是像原来那样指向对象的指针。我没有传递指向向量的指针,而是传递了它的引用。我访问该功能如下:

myVector[i].myFunction();

编译后,我发现 myFunction() 不再具有与以前相同的结果。我使用了一个断点并看到它正在改变它应该改变的属性,但是,这些改变从来没有影响到原始对象。即使断点显示 myVector[i] 的来源被更改,也没有最终翻译。

我尝试将指针传递给对象向量并使用:

(*myVector)[i].myFunction();

同样的事情,它编译但没有工作。

最后我尝试简单地传递对向量中第一个对象的引用,当然效果很好:

myObject.myFunction();

关于向量的引用是否缺少一些固有的东西?为什么指向指针向量的指针有效但对对象向量的引用不起作用?传递的向量不应该是原始向量的别名吗?为什么引用显示了变化,而不是它引用的对象?

除非我使用指针向量而不是对象向量,否则为什么我的更改不会生效。

【问题讨论】:

对向量的引用没有什么特别之处。问题可能出在其他地方。您能否发布一些更完整的代码,以便我们了解一些上下文? 啊谢谢大家,说得有道理,我不知道我怎么错过了。 如果对您有用,您可能希望将答案标记为“已接受”(通过单击复选标记)。 【参考方案1】:

等一下。当您更改此 sn-p 时:

(*myVector)[i]->myFunction()

到这里:

myVector[i].myFunction()

你实际上改变了两件事:

    myVector 从指针转到引用; myVector 中的元素类型从指针变为简单值类型。

如果您将元素的类型更改为简单值类型(如 std::vector<int*>std::vector<int>),那么当您将它们添加到向量时,它们会复制到其中。 (向量的传递方式,即通过指针或通过引用,不会影响这种行为。向量的传递方式和向量内部对象的传递方式是完全独立的。)这意味着无论何时您对它们进行更改,您只更改向量内的版本。

使用包含指针的向量没有任何问题(只要您以合理的方式进行内存管理)。如果您希望将向量中的版本更改复制到原始版本,则必须使用引用或指针。由于向量包含引用(如std::vector<int&>)是一个痛苦的世界,如果可能的话,您可能更喜欢指针。

【讨论】:

好答案。我会提醒新手(和专家)避免同时更改两个不熟悉的东西。【参考方案2】:

如果您的更改没有进入“原始”对象,则听起来您在某处按值传递。这里有一些想法。也许您可以发布更多代码?

    您是否将对象的副本放入向量中,并期望修改原始对象?

    问题可能是您的对象的复制构造函数没有复制所有成员。向量是否在增长?如果对象在向量内四处移动,那么让复制构造函数工作至关重要。

最后:

保持一个充满指针的向量,或容器安全的智能指针,通常比对象向量更合适,因为它避免了不必要的复制和破坏。除非对象非常小(例如具有一个数据成员的 Date 类),否则我不会将它们放入向量中,我会使用智能指针。

在这里传递一个指向向量的指针或对向量的引用都无关紧要。从概念上讲它们是不同的(引用不能为空),但在实现中它们都是指向向量的指针,并且向量不是按值传递的。

【讨论】:

我自己的非正式测试(很久以前在 Solaris 上完成)表明,应该在向量而不是对象中使用智能指针的时候,对象大约为 40 字节(或当然,如果他们有非平凡的复制/赋值语义)。当然,如果它是一个带有一个字段的日期,那么只存储日期会更有效,但对于可能有几个简单字段的 DateTimeRange 对象之类的东西可能也是如此。 是的,完美优化有一些界限,但它会成为一个移动的目标。如果它本质上是一个静态数组(尤其是在重写旧的 C 数组代码时),我会将一个大的具体类按值放入一个向量中。并且要注意过早的优化。【参考方案3】:

这个问题与你持有的是指针还是向量的引用无关。它与向量包含的内容有关。如果向量包含指针,那么当您更改向量中指向的对象时,相同对象存在的任何其他指针或引用也会受到影响。但是,如果您的向量包含对象(按值),那么您在插入时就是在复制它们,并且向量内部的更改不会在外部看到,反之亦然。

这是指针和引用的基本性质——如果它没有意义,你应该寻找一本不错的 C++ 书籍。

【讨论】:

【参考方案4】:

当向量存储对象时,它会存储传入的原始对象的副本。所以当你做这样的事情时

yourClass yourObj;
std::vector<yourClass> yourVector;
yourvector.push_back(yourObj);
yourvector[0].myFunction();

只有yourvector[0] 处的对象会更改,因为它是原始对象的副本。

【讨论】:

以上是关于c++ 引用向量的问题?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 向量指针/引用问题

通过引用传递向量 C++

在 C++ 中引用向量

C++ 通过引用传递向量字符指针

如何在 C++ 中通过引用返回向量

C++:试图理解通过引用传递向量