Removing Object From OwnedArray Without Moving Elements


#1

Is it possible to remove an object from an OwnedArray without moving subsequent objects to close the gap? I am using the following code to decide which window should be closed when the close button is pressed and when the indexes of the objects change the code I’m using to create windows behaves incorrectly.

void WindowList::closeWindow (ChangeBroadcaster* source)
{
    WindowDrawer* w = dynamic_cast<WindowDrawer*> (source);
    DBG ("Window Size Before Close: " + (String)windows.size());
    DBG ("Window Closing: " + (String)windows.indexOf(w));
    jassert (w != nullptr);

    #if ! JUCE_MAC
        if (windows.size() == 1)
        {
            JUCEApplicationBase::getInstance()->systemRequestedQuit();
        }
    #endif

    if (w->windowWantsToClose() == true)
    {
        windows.remove (windows.indexOf (w));
    }
    DBG ("Window Size After Close: " + (String)windows.size());
}

#2

Well, you should fix your code if it can’t deal with indexes changing!

But to answer the question, you can of course just replace an element with nullptr if you want to remove it, using OwnedArray::set()


#3

Another possible answer: an array is the wrong container. Maybe use instead something like:

std::list<std::unique_ptr<WindowDrawer>> drawerList;

Instead of indices you deal with iterators, that will always point to the correct element…


#4

Or just keep pointers directly to the objects in your OwnedArray, rather than indexes. Unlike an Array or vector, the objects in an OwnedArray are on the heap so a pointer to one won’t change.


#5

This was the approach I was using before. I removed the pointers to try and make the code as simple as possible, however I didn’t realise that remove changed the size of the OwnedArray until I started trying to use this approach. You learn from your mistakes right!