这是我的问题:
在我的GUI中,有几种类型的侦听器。它们存储在std::vector<WhateverListener*>
在我的GUI中,我有一个名为removeListeners
的方法,它看起来像这样:
void Widget::removeListeners( Widget* widget )
{
removeFocusListener((FocusListener*)widget);
removeMouseListener((MouseListener*)widget);
removeKeyboardListener((KeyboardListener*)widget);
removeWidgetListener((WidgetListener*)widget);
}
基本上,我认为不应该如何施展它;他们只是指针。我认为std::remove
只是比较指针,因此如果我提供一个小部件*那么它不会影响任何东西(我认为)。
删除功能的外观如下:
void Widget::removeWidgetListener(
WidgetListener *listener )
{
widgetListeners.erase(
std::remove(widgetListeners.begin(),
widgetListeners.end(), listener),
widgetListeners.end());
}
因此,在Widget析构函数中,我遍历小部件的子节点并调用removeListeners()
:
Widget::~Widget(void)
{
for(std::vector<Widget*>::iterator it = getChildBegin();
it != getChildEnd(); ++it)
{
(*it)->removeListeners(this);
(*it)->parentWidget = NULL;
(*it)->_container = NULL;
}
}
它不起作用。在一个正在听孩子的小工具上调用删除后,孩子们仍然有听众。
但是,如果我直接调用remove
方法,并且小部件继承自侦听器,则它可以工作:
Widget::~Widget(void)
{
for(std::vector<Widget*>::iterator it = getChildBegin();
it != getChildEnd(); ++it)
{
(*it)->removeWidgetListener(this);
(*it)->parentWidget = NULL;
(*it)->_container = NULL;
}
}
那为什么一个工作而另一个工作呢?我发现的唯一区别是,在第一个我正在为这种类型投射Widget。但我认为它只会比较指针,如果它们是==它会删除它吗?
答案 0 :(得分:2)
我担心您可能会受到C ++中对象标识和虚拟基类的攻击
http://www.parashift.com/c++-faq-lite/multiple-inheritance.html
基本上,将指针转换为多态基础并不能保证产生相同的指针值(当转换为(void *)时)。
确定没有查看更多的代码/窗口小部件类层次结构。
答案 1 :(得分:1)
您的问题的根源似乎是一个不正确的设计。正如你所做的那样需要强制转换意味着函数处于错误的位置。从你的帖子中不清楚Widgets和不同类型的Listener类之间的关系是什么。
您需要重新考虑调用removeListeners函数的位置,而不是将其放在基类析构函数中,您应该将它放在类的析构函数中,它实际上知道它是哪种类型的侦听器(并且只调用它纠正一个)。
如果没有详细了解课程之间的关系,很难更具体。一般来说,如果你必须施放,你应该问自己是否有更好的方法来实现强迫你施展的东西。