当我使用STL向量来存储类对象时,我发现了一个非常奇怪的副作用,其中push_back方法修改了现有数据!
基本上我有一个包含多个字段的类,如下所示:
class MyClass {
MyClass(std::string s, int i) {
StringValue = s;
IntValue = i;
}
std::string StringValue;
int IntValue;
}
我有一个包含 POINTERS 到MyClass对象的向量..然后我基本上推回对对象的引用:
std::vector<MyClass*> MyVector;
MyClass c1("CLASS 1", 1);
MyClass c2("CLASS 2", 2);
MyVector.push_back(&c1);
// Result:
// *MyVector[0] ==> ("Class 1", 1)
MyVector.push_back(&c2);
// Result:
// *MyVector[0] ==> ("Class 2", 2) ??why 2??
// *MyVector[1] ==> ("Class 2", 2)
你看到我得到的奇怪结果吗?我在每个push_back语句后都设置了断点,,,这个奇怪的事情发生了。
第一个push_back语句运行正常。但是第二个push_back语句 MODIFIED 第一个元素的内容,这对我来说没有意义..
我假设它与我存储引用而不是向量中的实际对象有关...但我无法弄清楚出了什么问题。
我该如何处理这个问题?任何见解?
由于
的更新:
(简化代码)
MyClass c1("CLASS 1", 1);
MyClass c2("CLASS 2", 2);
MyClass temp;
while (int i=0; i<2; i++) {
temp = c1;
MyVector.push_back(temp);
}
你们是对的,我得到的是我在这里做错了..实际的对象在每个循环中被破坏..在保持当前结构的同时解决这个问题的最佳方法是什么?我很难解释,但我想保留这个结构(将临时缓冲区保留在循环之外)..这可能吗?
答案 0 :(得分:4)
我会走出困境并利用我的精神力量来获得真实的代码,而不是问题中的简化代码。你的真实代码看起来像......鼓声......
class MyClass {
// ...
};
void addInstance(std::vector<MyClass*>& MyVector, int i) {
MyClass c("", i);
MyVector.push_back(&c);
}
int main() {
addInstance(MyVector, 1);
addInstance(MyVector, 2);
// ...
}
这是一个展示问题的工作示例,确实输出了&#34; 2,2&#34; (虽然因为您正在调用未定义的行为而无法保证):
编辑:我的通灵力量表示&#34;自动变量功能&#34;什么时候(现在我们有更新的问题)它真的是#34;在循环中自动变量&#34;。没有太大的错误。 : - )
您将自动变量的地址存储在其生命周期之外,这是不允许的。地址在每次调用时被重复使用,因此存储的每个指针都是相同的,并且碰巧指向最后用于存储最近创建的MyClass实例的内存(尽管不能保证)。
您需要(最好)存储这些自动变量的副本而不是指向它们的指针,或者(不太优选)使用new
创建它们,然后使用delete
删除它们。
要存储副本,您需要使用std::vector<MyClass>
。以下是您如何做到这一点的一个示例:http://ideone.com/4rIijM请注意,一旦您的类变得更复杂,您可能需要定义一个复制构造函数,析构函数和赋值运算符 - 查找&#34;规则3&#34 ;.如果你正在使用C ++ 11,那么也要查看&#34;规则的五个&#34;。