【发布时间】:2014-04-18 16:44:24
【问题描述】:
class C {
public:
std::vector<C*> list;
int value;
C(int value, C* parent)
{
this->value = value;
if(parent)
{
parent->registerChild(this);
}
}
void registerChild(C* child)
{
this->list.push_back(child);
}
~C()
{
for(std::vector<C*>::iterator it = list.begin(); it != list.end(); ++it)
{
if( (*it))
{
delete (*it);
}
}
}
};
这是一个 GUI 项目。有父类的子类必须通知父类,这样当父类被删除时,它的所有子类也应该被删除。
C* main = new C(100, 0);
C* child1 = new C(250, main);
C* child2 = new C(450, main);
delete main;
^ 一切正常 - main 与 child1 和 child2 一起被删除。
C* main = new C(100, 0);
C* child1 = new C(250, main);
C* child2 = new C(450, main);
delete child1;
delete main; // windows error
如果我决定先删除 child1,然后再决定删除 main,我会得到一个 Windows 错误,该错误可追溯到向量循环,显然 delete 试图删除一个现在不存在的指针。 我原以为 if( (*it)) 会为不再存在的指针返回 false。
我可以在这里做什么?
编辑: 这似乎完美无缺
class C {
typedef std::vector<C*> cList;
public:
std::vector<C*> list;
int value;
C* parent;
C(int value, C* parent)
{
this->value = value;
this->parent = parent;
if(parent)
{
parent->registerChild(this);
}
}
void registerChild(C* child)
{
this->list.push_back(child);
}
void removeChild(C* child)
{
cList::iterator it = std::find(list.begin(), list.end(), child);
if(it != list.end())
{
list.erase(it);
}
}
~C()
{
if(this->parent)
{
// this child is being removed - notify parent and remove this from its child_list
this->parent->removeChild(this);
}
cList::iterator it = list.begin();
while(it != list.end())
{
delete (*it);
// find a new beginning
it = list.begin();
};
}
};
【问题讨论】:
-
为什么不使用
unique_ptr或shared_ptr? -
这就是为什么你不想删除仍然有指向它们的东西的原因,也是存在各种形式的智能指针的主要原因之一。
-
我可能应该提到我还没有使用 C++11...
-
@Athlon1600 为什么你还没有使用 C++11?您应该标记您所在的版本。