уничтожить и построить класс, чтобы очистить его членов - PullRequest
0 голосов
/ 10 марта 2020

Я заметил, что в нашей кодовой базе есть некоторые классы, которые используются только для хранения данных в своих членах. Чтобы очистить члены, мы вызываем команду каждого класса clear (). Однако я также заметил, что методы clean вызывают другие операции очистки и, что в каскаде приводит к вызову clear () для типов данных std, таких как строка и векторы. Поэтому, кажется, написано огромное количество избыточного кода.

Чтобы свести к минимуму объем работы в процессе сокращения, я планирую обратить каждый понятный метод к следующему. Какие еще детали я могу упустить и ваши предложения?

void aClass::clear() {
this->~aClass();
*this = aClass();
}

Спасибо

Ответы [ 3 ]

1 голос
/ 10 марта 2020

Вам не хватает того, что ваш призыв к деструктору здесь неверен. Вы можете просто присвоить:

*this = aClass();

Однако тогда

  • Это не то, что должен делать метод clear. Вы создаете новый объект, а не очищаете его. Если вы clear a string, то перераспределение не должно произойти. Удаление string и создание нового - это действительно больше работы, а не меньше.
  • Как следствие первой точки, clear не принимает параметры, в то время как ваш конструктор, вероятно, делает. Опять же, создание по умолчанию нового экземпляра не то, что ожидается от clear, а иногда это даже невозможно (если нет конструктора по умолчанию).
  • Более того, допустим, вы реализуете clear как это. Затем метод не добавляет ничего, что пользователь класса не мог бы сделать с вызовом конструктора. Вместо x.clear(); они могли бы написать x = aClass();.

Резюме: если у вас есть много кода для clear объектов в вашей кодовой базе, то это очень вероятно по причине. Очистка экземпляра обычно выполняется с гораздо меньшими вычислительными затратами, чем создание нового экземпляра. С другой стороны, если это не так, то нет смысла реализовывать метод clear (при условии, что имеется доступный конструктор для создания нового экземпляра).

0 голосов
/ 10 марта 2020

Неееееееееееееееет.

Не делайте этого.

Деструктор - это не просто функция, которая вызывает некоторые операции над вашими членами.

Он заканчивается время жизни вашего объекта.

Период. Полная остановка.

Вы не можете вызвать деструктор, а затем продолжать использовать объект. Вызов его оператора присваивания с временным также не возвращает его к жизни; это просто вызывает оператор присваивания для изменения некоторых значений. Значения, которые больше не существуют.

В нескольких случаях разумно вызывать деструктор, но все они включают "очень ручное управление памятью" с использованием размещения new. В принципе нет других приемлемых времен для этого.

Просмотрите понятие времени жизни объекта в C ++.

Если ваш оператор присваивания копии написан правильно, то просто *this = aClass(); уже подходит для сброс ваших объектов. Вы могли бы также рассмотреть aClass().swap(*this), с соответствующей способностью к перемещению swap, добавляемой в ваш класс.

Это не «избыточные» операции.

0 голосов
/ 10 марта 2020

Какие еще детали я могу пропустить

Деструктор по-прежнему очищает стандартные уничтоженные контейнеры. Не только это, но и воссоздает их по стоимости.

Ссылки на очищенный объект станут недействительными. Это может легко привести к неопределенному поведению, если вы не будете осторожны.

и ваши предложения?

Напишите нормальную функцию, которая не включает уничтожение объекта.

...