所以我在向量中搜索一个元素,我将它存储在一个迭代器中,然后在其上调用erase()
。不幸的是,当我设置断点并检查发生了什么时,我发现即使closestObjectIt
指向正确的元素,该元素仍然保留在向量中,其他一些元素也会被删除。我不知道这里有什么问题;为什么没有删除正确的迭代器?
我的项目中也有一些从std::vector
到cv::vector
(来自OpenCV)的隐式转换,反之亦然,但是我将它们排除在外,并且是可疑的。
DetectedObject Head:: findTheClosestObjectFromObjects(std::vector<DetectedObject>& objects)
{
float minDistance = 10000;
std::vector<DetectedObject>::iterator closestObjectIt;
DetectedObject closestObject = objects[0];
for(std::vector<DetectedObject>::iterator it = objects.begin(); it != objects.end(); ++it)
{
float distance = computeDistance2((*it));
if (distance < minDistance)
{
minDistance = distance;
closestObject = (*it);
closestObjectIt = it;
}
}
std::cout << "Before erease: " << std::endl;
objects.erase(closestObjectIt);
std::cout << "After erease: " << std::endl;
return closestObject;
}
答案 0 :(得分:3)
上面的代码看起来不错,您是否尝试过查看DetectedObject
的复制赋值运算符?擦除元素时,这就是使用(在c ++ 03中)移动向量中的其他元素,因此这里的错误将使erase
正常运行。
答案 1 :(得分:0)
vector :: erase(it)不会删除其指向的元素。它调用复制管理对象的分配,以将其指向的元素分配给下一个对象。此步骤也将在下一个步骤中执行,并继续直到到达end元素为止,这实际上将删除end元素的内存。 因此,请记住为Class编写副本赋值运算符,该运算符将在vector中进行管理,并将与delete()方法一起使用。解决此问题的第二种方法是使用Pointer的std :: vector。
#include <iostream>
#include <vector>
using namespace std;
class BarcodeTagging {
int value_;
public:
BarcodeTagging(int value) : value_(value) {
}
~BarcodeTagging() {
std::cout << "Delete " << this << "\n";
}
const BarcodeTagging& operator=(const BarcodeTagging& other) {
std::cout << "Call to this \n";
std::cout << "who calling: " << this << "\n";
std::cout << "who is called: " << &other << "\n";
value_ = other.value_;
return *this;
}
int GetValue() const {
return value_;
}
};
int main() {
// your code goes here
std::vector<BarcodeTagging> taggings;
BarcodeTagging tag1(1);
BarcodeTagging tag2(2);
BarcodeTagging tag3(3);
taggings.push_back(tag1);
taggings.push_back(tag2);
taggings.push_back(tag3);
std::cout << "Before erase \n";
for (int i = 0; i < taggings.size(); ++i) {
std::cout << "element " << i << ": " << &(taggings[i]) << ", with value: " <<
taggings[i].GetValue() << "\n";
}
taggings.erase(taggings.begin());
std::cout << "After erase \n";
for (int i = 0; i < taggings.size(); ++i) {
std::cout << "element " << i << ": " << &(taggings[i]) << ", with value: " <<
taggings[i].GetValue() << "\n";
}
return 0;
}
输出:
Delete 0x55faf3c98c20
Delete 0x55faf3c98c40
Delete 0x55faf3c98c44
Before erase
element 0: 0x55faf3c98c20, with value: 1
element 1: 0x55faf3c98c24, with value: 2
element 2: 0x55faf3c98c28, with value: 3
Call to this
who calling: 0x55faf3c98c20
who is called: 0x55faf3c98c24
Call to this
who calling: 0x55faf3c98c24
who is called: 0x55faf3c98c28
Delete 0x55faf3c98c28
After erase
element 0: 0x55faf3c98c20, with value: 2
element 1: 0x55faf3c98c24, with value: 3
Delete 0x7ffe1d958b40
Delete 0x7ffe1d958b30
Delete 0x7ffe1d958b20
Delete 0x55faf3c98c20
Delete 0x55faf3c98c24