我有一个包含对向量引用的结构。
然后我创建了这个结构的向量。我在这个向量中创建了这个结构的三个三个实例。
然后我在向量中擦除结构的第二个实例。
这显然导致testData2的内容与testData3的内容相同!?
如何阻止这种情况发生?我应该在结构的析构函数中放置一些东西来阻止这种情况发生吗?
或者我在这里做的非常糟糕,如果是这样,为什么?
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
struct TESTSTRUCT
{
int &testInt;
std::vector<int> &testVector;
TESTSTRUCT(int &testIntInput, std::vector<int> &testVectorInput)
:testInt(testIntInput), testVector(testVectorInput) {}
TESTSTRUCT(const TESTSTRUCT &source)
:testInt(source.testInt), testVector(source.testVector) {}
TESTSTRUCT &operator=(const TESTSTRUCT &source)
{
testInt = source.testInt;
testVector = source.testVector;
return *this;
}
virtual ~TESTSTRUCT(){}
};
int main()
{
std::vector<int> testData1;
std::vector<int> testData2;
std::vector<int> testData3;
int a = 1;
int b = 2;
int c = 3;
testData1.push_back(10);
testData1.push_back(20);
testData1.push_back(30);
testData2.push_back(40);
testData2.push_back(50);
testData2.push_back(60);
testData3.push_back(70);
testData3.push_back(80);
testData3.push_back(90);
std::vector<TESTSTRUCT> *structVector = new std::vector<TESTSTRUCT>();
structVector->push_back(TESTSTRUCT(a, testData1));
structVector->push_back(TESTSTRUCT(b, testData2));
structVector->push_back(TESTSTRUCT(c, testData3));
std::cout<<&testData1[0]<<std::endl;
std::cout<<&testData2[0]<<std::endl;
std::cout<<&testData3[0]<<std::endl;
std::cout<<testData1[0]<<std::endl;
std::cout<<testData2[0]<<std::endl;
std::cout<<testData3[0]<<std::endl;
structVector->erase(structVector->begin()+1);
std::cout<<testData1[0]<<std::endl;
std::cout<<testData2[0]<<std::endl;
std::cout<<testData3[0]<<std::endl;
std::cout<<&testData1[0]<<std::endl;
std::cout<<&testData2[0]<<std::endl;
std::cout<<&testData3[0]<<std::endl;
return 0;
}
输出:
00711220
00711258
00717C68
10
40
70
10
70
70
00711220
00711258
00717C68
Press any key to continue . . .
编辑:
这是一个较大程序的例子。结构的实例是我希望渲染器绘制的东西,这些东西可以改变它们的位置(因此渲染器应该绘制它们的位置)。
答案 0 :(得分:0)
问题无法立即显现。看看TESTSTRUCT
:
TESTSTRUCT &operator=(const TESTSTRUCT &source)
{
testInt = source.testInt;
testVector = source.testVector;
return *this;
}
testVector
中的this
将获得source.testVector
的副本。
现在,structVector
中的main
包含三个TESTSTRUCT
个实例,每个实例都通过引用绑定到自己的std::vector<int>
。当您致电structVector->erase(structVector->begin()+1);
时,TESTSTRUCT(b, testData2)
已移除structVector
。
erase
的规范表示在请求的擦除位置之后的所有向量元素向下移位(就位置而言),以便向量是存储器连续的。我不知道标准是否指定了在复制时需要实现erase
的方式,但在我的实现(g ++)中,调用了operator=
。这意味着通过引用在迭代器TESTSTRUCT
引用的structVector->begin()+1
实例中存储的向量(实际上,structVector[1]
)获取structVector[2]
的内容。因为它是一个参考,它与testData2
中的main
基本相同,这解释了为什么它的内容与testData3
完全相同。
然而,这是有效的,因为您可以看到自己,在调试时避免使用这些代码。
答案 1 :(得分:0)
你过度使用引用(有点不正确)。您的TESTSTRUCT
个对象包含对testdata1
,testdata2
和testdata3
的引用。因此,当您修改structVector
时,前两个向量也会被修改。因此,当您从structVector
中删除第二个元素时,第三个元素会占据它的位置。因此,内部元素(即testdata2
)也会替换为main中的testdata3
,因为它们的引用包含在struct
中。