Вам нужно не только определить деструктор для выполнения очистки, но также объявить (и при необходимости определить) конструктор копирования и оператор присваивания для вашего класса, чтобы убедиться, что копии сделаны правильно.
Неявно определенный деструктор уничтожает переменные-члены.Так, например, если у вас была переменная-член типа string
, деструктор уничтожит эту переменную самостоятельно.Однако деструктор для указателя (например, string*
) не предназначен: вы несете ответственность за уничтожение объекта, на который указывает указатель.
Вам также необходимо определить операции копирования для этого класса или вкак минимум подавить генерацию операций копирования по умолчанию, которые предоставляет вам компилятор.Зачем?Потому что по умолчанию операции копирования просто копируют каждую переменную-член.Так, если, например, вы должны были написать:
{
Foo x;
Foo y(x);
} // Uh oh
Оба x
и y
уничтожаются в конце блока.На этом этапе и x
, и y
указывают на один и тот же динамически распределенный мьютекс и строку, поэтому мьютекс и строка будут уничтожены дважды (один раз для x
и один раз для y
).
Лучший вариант - вообще не использовать ручное выделение памяти.Скорее, вы должны сделать someString
прямым членом класса (то есть объявить его string someString;
) или использовать какой-нибудь умный указатель для управления его временем жизни (например, unique_ptr
или shared_ptr
).Точно так же вы должны использовать умный указатель с пользовательским средством удаления для управления временем жизни мьютекса, если ваш класс не является копируемым, и в этом случае вы можете сделать мьютекс прямым членом класса.