简体   繁体   English

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

[英]std::remove is not removing from std::vector

Here is my issue: In my GUI, there are several types of listeners. 这是我的问题:在我的GUI中,有几种类型的监听器。 They are stored in std::vector<WhateverListener*> 它们存储在std::vector<WhateverListener*>

In my GUI, I have a method called removeListeners and it looks like this: 在我的GUI中,我有一个名为removeListeners的方法,它看起来像这样:

void Widget::removeListeners( Widget* widget )
{
    removeFocusListener((FocusListener*)widget);
    removeMouseListener((MouseListener*)widget);
    removeKeyboardListener((KeyboardListener*)widget);
    removeWidgetListener((WidgetListener*)widget);
}

Basically, I do not think it should matter how I cast it; 基本上,我不认为我应该如何施展它; they are just pointers. 他们只是指针。 I think std::remove simply compares pointers, therefore if I provide a widget* then it shouldn't affect anything (I think). 我认为std::remove只是比较指针,因此如果我提供一个小部件*那么它不会影响任何东西(我认为)。

How the remove functions look is something like this: remove函数的外观如下所示:

void Widget::removeWidgetListener( 
                                    WidgetListener *listener )
{
    widgetListeners.erase(
        std::remove(widgetListeners.begin(),
        widgetListeners.end(), listener),
        widgetListeners.end());
}

So, in the Widget destructor, I iterate through the widget's children and call removeListeners() : 因此,在Widget析构函数中,我遍历窗口小部件的子removeListeners()并调用removeListeners()

Widget::~Widget(void)
{

    for(std::vector<Widget*>::iterator it = getChildBegin();
        it != getChildEnd(); ++it)
    {
        (*it)->removeListeners(this);
        (*it)->parentWidget = NULL;
        (*it)->_container = NULL;
    }

}

It does not work. 这是行不通的。 After calling delete on a Widget which was listening to its children, the children still had listeners. 在一个正在听孩子的小工具上调用删除后,孩子们仍然有听众。

However, if I call the remove methods directly, and the widget inherits from the listener, it works: 但是,如果我直接调用remove方法,并且小部件继承自侦听器,则它可以工作:

Widget::~Widget(void)
{

    for(std::vector<Widget*>::iterator it = getChildBegin();
        it != getChildEnd(); ++it)
    {
        (*it)->removeWidgetListener(this);
        (*it)->parentWidget = NULL;
        (*it)->_container = NULL;
    }

}

So why does one work and not the other? 那为什么一个工作而另一个工作呢? The only difference I spot is that in the first one I'm casting a Widget to that type. 我发现的唯一区别是,在第一个我正在为这种类型投射Widget。 But I thought it would just compare pointers and if they were == it would remove it? 但我认为它只会比较指针,如果它们是==它会删除它?

I'm afraid you might be getting stung by object identity and virtual base classes in C++ 我担心你可能会受到C ++中对象标识和虚拟基类的攻击

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

Basically, converting pointers to polymorphics bases, is not guaranteed to result in identical pointer values (when cast to (void*) eg). 基本上,将指针转换为多态基础不能保证产生相同的指针值(当转换为(void *)时)。

It should work as long as you store the exact same pointer type as what you cast it to during removal, but I can't be sure without looking at more of your code/widget class hierarchy. 只要您存储完全相同的指针类型 ,你拆卸过程中它转换为应该工作,但不看更代码/部件类层次结构的我不能肯定。

The root of your issue seems to be an incorrect design. 问题的根源似乎是一个不正确的设计。 The need to cast as you are doing implies that the function is in the wrong place. 正如你所做的那样需要强制转换意味着函数处于错误的位置。 It's not clear from your post what the relationship between Widgets and the different types of Listener classes are. 从你的帖子中不清楚Widgets和不同类型的Listener类之间的关系是什么。

You need to rethink where you are calling the removeListeners function from and instead of putting it in the base class destructor, you should put it in the destructor of the class that actually knows which type of listener it is (and only call the correct one). 您需要重新考虑调用removeListeners函数的位置,而不是将其放在基类析构函数中,您应该将它放在类的析构函数中,它实际上知道它是哪种类型的侦听器(并且只调用正确的类) 。

It's hard to be more specific without getting some more detail on the relationships between your classes. 如果不详细了解类之间的关系,就很难更具体。 In general, if you have to cast, you should ask yourself if there is a better way to accomplish what it is that's forcing you to cast. 一般来说,如果你必须施展,你应该问自己是否有更好的方法来实现强迫你施展的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM