Что меня смущает, так это то, почему Array должен вызывать этот деструктор, так как он в основном является указателем на первый элемент и поэтому не является объектом, выходящим из области видимости.
Массив является , а не указателем. Если бы это было так, у нас были бы только указатели. Имя массива может и действительно затухает до указателя на первый элемент в массиве (что может сильно раздражать), но это не указатель. Это объект, который хранит N
объекты в непрерывном фрагменте памяти, и информация о размере является частью его типа. Это означает, что int[5]
отличается от типа int[6]
.
Что здесь происходит, это
Test TestArray[3]={A,B,C};
создает массив из трех Test
, а затем копирует инициализирует каждый Test
объект в массиве из инициализаторов {A,B,C}
. Поэтому, когда main
заканчивается, TestArray
уничтожается, вызывайте деструктор для каждого элемента. А затем C
, B
и A
как уничтоженные в этом порядке.
Это проблема для вас, так как ваш класс просто использует конструктор копирования по умолчанию. Это означает, что каждый объект в массиве имеет копию точки объекта, которой он был инициализирован, и указывает на ту же память. Поэтому, когда массив уничтожается, delete
вызывается во всех указателях-членах, а затем C
, B
и A
снова пытаются удалить ту же самую память, что является неопределенным поведением.
Что вам нужно сделать, это следовать правилу из трех и создать специальные функции-члены, чтобы ваш класс копировался правильно, или вы можете использовать RAII в форме интеллектуальных указателей / std::vector
и пусть они справятся со всем этим для вас, и вы можете использовать правило нуля