С++. 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 шт):
Если вы добавляете в вектор элемент, а в нем заканчилась емкость (.capacity()) - он выделяет себе новый кусок памяти в куче (большего размера), перемещает в него элементы (вызывает перемещающие или копирующие конструкторы), и удаляет старый блок.
Когда старый блок памяти удаляется, для объектов в нем вызываются деструкторы.
Ваша проблема из-за того, что Mp3Window нарушает правило трех/пяти/нуля (на русском) - если вы добавляете классу кастомный деструктор, нужно также добавить правильные копирующие конструктор и оператор присваивания ("три"). Если класс по смыслу нельзя копировать, то их нужно хотя бы удалить (=delete). В некоторых случаях нужны еще перемещающие конструктор и оператор присваивания ("пять").
Или, если это сложно, тогда запертить копирование/перемещение класса:
Mp3Window(const Mp3Window &) = delete;
Mp3Window &operator=(const Mp3Window &) = delete;
Теперь вектор откажется хранить такой класс.
Вместо него можно взять, например, std::list, которому не нужно копировать элементы.
