类Refvect { 上市: 矢量& refv; Refvect(int t,vector& refv = vector()):refv(refv){}; void operator()() { refv.clear(); } }; int main() { Refvect r(0); R(); }
使用Visual Studio 2010,这给我一个错误:执行时“矢量迭代器不兼容”,但我不明白为什么(但我可以在refv中插入元素而没有任何问题)。 临时对象vector()与引用一样长,没有?
答案 0 :(得分:4)
声明一旦
Refvect r(0);
执行(控制超过分号),临时vector<int> &refv = vector<int>()
被销毁。现在存储在类对象中的引用是悬空 - 不绑定到任何活动对象。尝试通过此类引用访问对象是未定义的行为。
答案 1 :(得分:1)
临时对象vector()生活为 只要参考,没有?
没有!
Temporaries在最外层的封闭表达式的末尾破坏 - 即嵌入在语句而不是另一个表达式中的表达式。没有魔法跟踪引用,以确保对象只要引用它们就可以存活 - 这将是垃圾收集。
<强>更新强>
回应你的评论:
如果我使用
const vector<int> &refv;
它 作品
我不确定那是怎么回事。如果将const
添加到参数refv
,则它不再与该成员兼容,因此不应编译。如果您还将成员更改为const
,那么您应该会发现无法在其上调用clear
,因为它不是const
成员函数。
如果你在C ++中找到了“似乎有用”的东西,那么你就完全以错误的方式使用C ++了!
在高度特定的特殊情况下,有很多方法可以让某些东西在C ++中“工作”,但如果这些情况发生变化,这些方法会更明显地失败。这被称为“未定义的行为” - 结果可能包括明显正确的行为,有时候。
最常见的形式是数据即使在仍有访问权限的情况下也不再有效,这就是您在这里的情况。
使用C ++的正确方法是彻底了解已定义行为的限制,并尽可能保持在其中。特别是,您需要了解对象的生存时间,因此您可以确保对对象的引用的寿命不会超过它们引用的对象。