С++. vector произвольно вызывает деструктор клсса

С++. vector произвольно вызывает деструктор клсса, при добавлении нового элемента.

Есть класс и сразу создан вектор этого класса

class Mp3Window
{

public:
    float Balans;
    float Volume;
    bool Init;
    Mp3Window()
    {
        Init = 0;
        Balans = 0;
        Volume = 0;
    }
    HSAMPLE sample;
    HCHANNEL channel;
    std::string SubName;


    std::string URL;





    //DevChBTG::OBGECT Procces;
    int idObject;
    int idPlay;
    int idPause;
    int idGrup;

    int idTextKey;
    char key;

    int Temp;

    ~Mp3Window()
    {

        {
            BASS_ChannelStop(channel);
            BASS_StreamFree(channel);
        }
    }

};

std::vector<Mp3Window>MusMAs;

Вот код добавления нового элемента

{
            Mp3Window W;
            MusMAs.push_back(W);
        }
            int id = MusMAs.size()-1;
            MusMAs[id].idGrup = ID1;
            MusMAs[id].idObject = GUI.FindIdObject("CoPres1track",ID1);
            MusMAs[id].idPause = GUI.FindIdObject("CoPres1Pause",ID1);
            MusMAs[id].idPlay = GUI.FindIdObject("CoPres1Play",ID1);
            MusMAs[id].idTextKey = GUI.FindIdObject("CoPres1key",ID1);
            MusMAs[id].URL = URL;
            MusMAs[id].Init = true;
            GUI.mObgects[MusMAs[id].idTextKey].Text = "";




                //nameMP3->Text = utf8_encode( utf8_decode(S).c_str());
                MusMAs[id].sample = MUS;
                MusMAs[id].channel=BASS_SampleGetChannel(MusMAs[id].sample, FALSE); 
                //BASS_ChannelPlay(MusMAs[MusMAs.size()-1].channel, FALSE); //Запуск в начале

В результате при добавлении нового элемента в старом вызывается деструктор и песня удаляется на картинке видно результат утраты доступа к песне (переменных)

введите сюда описание изображения

Если закоментировать деструктор все работает отлично введите сюда описание изображения

Как не комментируя деструктор заставить все работать


Ответы (1 шт):

Автор решения: HolyBlackCat

Если вы добавляете в вектор элемент, а в нем заканчилась емкость (.capacity()) - он выделяет себе новый кусок памяти в куче (большего размера), перемещает в него элементы (вызывает перемещающие или копирующие конструкторы), и удаляет старый блок.

Когда старый блок памяти удаляется, для объектов в нем вызываются деструкторы.

Ваша проблема из-за того, что Mp3Window нарушает правило трех/пяти/нуля (на русском) - если вы добавляете классу кастомный деструктор, нужно также добавить правильные копирующие конструктор и оператор присваивания ("три"). Если класс по смыслу нельзя копировать, то их нужно хотя бы удалить (=delete). В некоторых случаях нужны еще перемещающие конструктор и оператор присваивания ("пять").


Или, если это сложно, тогда запертить копирование/перемещение класса:

Mp3Window(const Mp3Window &) = delete;
Mp3Window &operator=(const Mp3Window &) = delete;

Теперь вектор откажется хранить такой класс.

Вместо него можно взять, например, std::list, которому не нужно копировать элементы.

→ Ссылка