std :: remove没有从std :: vector中删除

时间:2011-04-24 23:19:17

标签: c++ std

这是我的问题: 在我的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。但我认为它只会比较指针,如果它们是==它会删除它吗?

2 个答案:

答案 0 :(得分:2)

我担心您可能会受到C ++中对象标识和虚拟基类的攻击

http://www.parashift.com/c++-faq-lite/multiple-inheritance.html

基本上,将指针转换为多态基础并不能保证产生相同的指针值(当转换为(void *)时)。

确定没有查看更多的代码/窗口小部件类层次结构。

答案 1 :(得分:1)

您的问题的根源似乎是一个不正确的设计。正如你所做的那样需要强制转换意味着函数处于错误的位置。从你的帖子中不清楚Widgets和不同类型的Listener类之间的关系是什么。

您需要重新考虑调用removeListeners函数的位置,而不是将其放在基类析构函数中,您应该将它放在类的析构函数中,它实际上知道它是哪种类型的侦听器(并且只调用它纠正一个)。

如果没有详细了解课程之间的关系,很难更具体。一般来说,如果你必须施放,你应该问自己是否有更好的方法来实现强迫你施展的东西。