use*_*186 0 c++ pointers reference vector
当我使用STL向量存储类对象时,我观察到一个非常奇怪的副作用,其中push_back方法修改了现有数据!
基本上我有一个包含多个字段的类,如下所示:
class MyClass {
MyClass(std::string s, int i) {
StringValue = s;
IntValue = i;
}
std::string StringValue;
int IntValue;
}
Run Code Online (Sandbox Code Playgroud)
我有一个向量,其中包含指向 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)
Run Code Online (Sandbox Code Playgroud)
你看到我得到的奇怪结果了吗?我在每个push_back语句之后设置了断点,并且发生了这种奇怪的事情。
第一个 Push_back 语句工作正常。但是第二个push_back语句修改了第一个元素的内容,这对我来说没有意义。
我假设它与我存储引用而不是向量内的实际对象有关......但我无法弄清楚出了什么问题。
我该如何处理这个问题?有什么见解吗?
谢谢
更新:
(简化代码)
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);
}
Run Code Online (Sandbox Code Playgroud)
你们是对的,我明白我在这里做错了什么。实际的对象在每个循环中都会被破坏。在保持当前结构的同时解决这个问题的最佳方法是什么?我很难解释,但我想保留这个结构(将临时缓冲区保留在循环之外)..这可能吗?
我将竭尽全力,用我的心灵力量来推导真正的代码,而不是问题中的简化代码。你的真实代码看起来像...鼓声...
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);
// ...
}
Run Code Online (Sandbox Code Playgroud)
这是一个演示该问题的工作示例,它确实输出“2, 2”(尽管不能保证这一点,因为您正在调用未定义的行为):
编辑:我的心灵力量说“函数中的自动变量”(现在我们有了更新的问题)它实际上是“循环中的自动变量”。还不错。:-)
您存储的自动变量的地址超出了其生命周期,这是不允许的。该地址在每次调用时都会重复使用,因此存储的每个指针都是相同的,并且恰好指向最后用于存储最近创建的 MyClass 实例的内存(尽管不能保证)。
您需要(最好)存储这些自动变量的副本而不是指向它们的指针,或者(不太优选)使用 来创建它们new,然后使用 来删除它们delete。
要存储副本,您需要使用std::vector<MyClass>. 以下是如何做到这一点的示例:http://ideone.com/4rIijM 请注意,一旦您的类变得更加复杂,您可能需要定义复制构造函数、析构函数和赋值运算符 - 查找“三法则”。如果您使用的是 C++11,还要查找“五规则”。
| 归档时间: |
|
| 查看次数: |
1107 次 |
| 最近记录: |