向量的C++参考

Posted

技术标签:

【中文标题】向量的C++参考【英文标题】:C++ Reference of vector 【发布时间】:2010-05-03 15:31:58 【问题描述】:

类反射 上市: 向量 &refv; Refvect(int t, 向量 &refv = vector()) : refv(refv) ; 无效运算符()() refv.clear(); ; 主函数() 反射 r(0); r();

使用 Visual Studio 2010,这给了我一个错误:执行时“向量迭代器不兼容”,但我不明白为什么(但我可以在 refv 中插入元素而没有任何问题)。 临时对象 vector() 和引用一样长,不是吗?

【问题讨论】:

请注意,将临时对象绑定到非 const 引用的能力是 VS 扩展,标准只允许将临时对象绑定到 const 引用。 @avakar - 大约 12 年来仅“应要求”提供向后兼容性。默认是符合标准的。 @Daniel Earwicker,我不知道您所说的“应要求”是什么意思。我刚刚在 vs10 中创建了一个新的空项目,并且无需请求任何内容即可将临时对象绑定到非常量引用。 Visual Studio 实际上的行为方式正好相反——如果需要,您必须请求标准行为 (/Za)。 简直不敢相信……怎么还是还是这样?我在 VS 6 中得到的印象是它已被修复(我认为他们必须修复很多自己的库代码,并且当时为此感到自豪)。 【参考方案1】:

只要声明

Refvect r(0);

被执行(控制超出分号)临时的vector<int> &refv = vector<int>() 被销毁。现在存储在类对象中的引用是 dangling - 没有绑定到任何活动对象。尝试通过此类引用访问对象是未定义的行为。

【讨论】:

+1。应该存储实际向量而不是对该向量的副本。 @Billy - 不。大多数时候应该存储实际向量的副本,而不是对原始向量的引用。 @Noah Roberts:感谢您发现我的错字。请将“副本”替换为“参考” 如果它这样做了,@Billy,它就不再是 Refvect 了。存储引用似乎是该类的全部目的。唯一必要的更改似乎是消除默认参数的可能性。换句话说,当你想要一个向量引用时,你需要提供你自己的向量;引用类不能提供它自己的一个——至少不能通过默认参数。 @Rob Kennedy:我认为这门课就是一个例子;不是真正的代码。如果它的目的是存储引用,那么 OP 应该存储引用,而不是唯一目的是包含该引用的类。【参考方案2】:

临时对象 vector() 存在于 只要是参考,不是吗?

不!

临时变量在最外层的封闭表达式的末尾进行破坏 - 即嵌入在语句中而不是另一个表达式中的表达式。没有神奇的引用跟踪来确保对象与对它们的引用一样长 - 这将是垃圾收集。

更新:

回应您的评论:

如果我使用const vector<int> &refv; 它 作品

我不确定这是怎么回事。如果将const 添加到参数refv,则它不再与成员兼容,因此不应编译。如果你也将成员更改为const,那么你应该会发现你不能在其上调用clear,因为它不是const 成员函数。

如果你在 C++ 中发现了“似乎可以工作”的东西,那么你就是在以完全错误的方式使用 C++!

在高度特定的特殊情况下,有很多方法可以在 C++ 中“似乎工作”,但如果改变这些情况,这些方法会更明显地失败。这称为“未定义行为” - 结果可能包括明显正确的行为,有时。

最常见的形式是数据不再有效,即使仍然有访问它的方法,这就是您在此处遇到的情况。

使用 C++ 的正确方法是彻底了解已定义行为的限制,并尽可能地留在其中。特别是,您需要了解对象的寿命,以便确保对对象的引用不会比它们所引用的对象寿命更长。

【讨论】:

好的,谢谢,但现在如果我使用 const vector &refv;有用吗?

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

C++ STL 中向量的恒定时间交换逻辑

标准模板库使用参考——vector向量容器

全局向量 C++

带有继承的c++向量

向量 C++ 上的 Memset

使用步骤 c++ 构建向量