我创建了一个类,它创建了一个新的对象指针列表:
FeatureSet::FeatureSet() {
this->featuresList = new list<HaarFeature*>;
globalCounter = 0;
}
现在我想从列表中删除所有对象,然后删除指向列表的指针。我的代码是:
FeatureSet::~FeatureSet() {
for (list<HaarFeature*>::iterator it = featuresList->begin(); it != featuresList->end(); it++) {
delete *it;
}
delete featuresList; // this take a long time (more than half a minute)
}
我的问题是解决这个问题的最佳方法是什么?我的方法是否正确?不幸的是,目前最后一次操作(删除指向列表的指针)大约需要半分钟。列表有大约250000个对象。
答案 0 :(得分:1)
您确实需要使用不同的数据结构。根据您的突变模式,使用deque
或vector
等容器可能会更好。
答案 1 :(得分:1)
你的方法是正确的。这似乎是做你想做的事情的合适方式。但list
解除分配是昂贵的。也许尝试不同的数据结构?
以下内容:
for (; _Pnode != _Myhead; _Pnode = _Pnext)
{ // delete an element
_Pnext = _Nextnode(_Pnode);
this->_Alnod.destroy(_Pnode);
this->_Alnod.deallocate(_Pnode, 1);
}
是代码大部分时间花费的地方。它需要遍历所有节点并删除它们。对于list
来说,真的没办法解决这个问题。
我建议你使用std::vector
,解除分配要快得多。
答案 2 :(得分:0)
鉴于您正在使用列表,是的,这是删除子元素的方法。请注意,无论您使用何种容器,如果您要存储指针,请执行“获取下一个指针并将其删除”的操作。很可能需要相同的时间。它当然值得测试作为练习。
您可以节省删除容器(以及它包含的节点)本身。但父容器的选择更可能取决于它在其他地方的用法。例如:如果您要逐个添加节点,则向量必须重新分配并复制整个指针块以维持其内部结构。
那就是说,我也同意上面关于容器本身动态分配的观点。不妨使它成为具体的成员变量。 (当然你仍然需要迭代它并删除节点子内容。但这更像是约定的功能而不是其他任何东西。
答案 3 :(得分:0)
行。所以我进行了一些研究。我刚刚测试了四种解决方案。结果如下表所示:(我无法放置图片,请点击链接)
Comparing an efficiency of list and vector containers
从表中可以看出,包含对象的向量是最快的解决方案。存储指向对象的指针比包含实际对象要慢得多。
内容:
回答@Emile Cormier提出的问题 - 为什么我要使用指向容器的指针?这确保即使在删除父类对象后也可以访问向量/列表元素。请考虑这部分代码:
class A{
public:
A(){
this->test = new vector<int>;
for(int i = 0; i < 10; i++){
test->push_back(i);
}
}
~A(){
cout << "object A is dead\n";
test->clear(); // <--- COMMENTING this line allows to access to the vector's elements "after death" without copying
}
vector<int>* GetPointer(){
return this->test;
}
private:
vector<int>* test;
};
class B{
public:
B(){
for(int i = 0; i < 10; i++){
test.push_back(i);
}
}
~B(){
cout << "object B is dead\n";
test.clear();
}
vector<int> GetbyValue(){
return test;
}
private:
vector<int> test;
};
cout << "\nCASE A\n";
A* instance = new A();
vector<int>* local = instance->GetPointer();
delete instance; //deletion before calling!!!
//Access is impossible, because clear method in destructor destroys original vector, connected with pointer
cout << "Printing A\n";
for(int i = 0; i < local->size(); i++){
cout << (*local)[i] << "\n";
}
cout << "\nCASE B\n";
B* instance2 = new B();
vector<int> local2 = instance2->GetbyValue();
delete instance2; //deletion before calling!!!
//Access is still possible, because vector has been copied to local variable
cout << "Printing B\n";
for(int i = 0; i < local2.size(); i++){
cout << (local2)[i] << "\n";
}
cout << "THE END\n";
当我不使用指向矢量的指针(情况B)时,我虽然可以在删除“B”类对象后从矢量访问对象但实际上我使用了返回矢量的本地副本。使用指向vector的指针(情况A)允许我甚至在删除“A”类对象后获得对矢量对象的访问权限,当然我当然没有手动调用析构函数中的clear()方法。
最后 - 感谢大家的帮助。我认为我的问题已经解决了。