Да, это нормально. Если класс поддерживает такое использование, клиентам не нужно синхронизировать уничтожение; то есть им не нужно следить за тем, чтобы все другие методы объекта завершили до вызова деструктора.
Я бы порекомендовал клиентам не предполагать, что они могут сделать это, если это явно не задокументировано. Клиенты по умолчанию несут такую нагрузку, в частности, со стандартными объектами библиотеки (§17.6.4.10 / 2).
Есть случаи, когда это хорошо, хотя; Деструктор std::condition_variable
, например, специально разрешает текущие вызовы condition_variable::wait()
метода при запуске ~condition_variable()
. Требуется только, чтобы клиенты не инициировали вызовы wait () после запуска ~condition_variable()
.
Может быть, чище потребовать, чтобы клиент синхронизировал доступ к деструктору - и конструктору в этом отношении, - как это делает большинство остальных стандартных библиотек. Я бы порекомендовал сделать это, если это возможно.
Однако существуют определенные схемы, в которых может иметь смысл освободить клиентов от бремени полной синхронизации уничтожения. Общий шаблон condition_variable
выглядит примерно так: рассмотрите возможность использования объекта, который обрабатывает, возможно, долго выполняющиеся запросы. Пользователь делает следующее:
- Построить объект
- Заставить объект получать запросы от других потоков.
- Заставить объект перестать получать запросы: в этот момент некоторые невыполненные запросы могут выполняться, но новые не могут быть вызваны.
- Уничтожить объект. Деструктор будет блокироваться до тех пор, пока все запросы не будут выполнены, в противном случае текущие запросы могут иметь плохое время.
В качестве альтернативы может потребоваться, чтобы клиенты действительно синхронизировали доступ. Вы можете вообразить шаг 3.5 выше, где клиент вызывает метод shutdown()
для объекта, который выполняет блокировку, после чего клиент может безопасно уничтожить объект. Однако у этой конструкции есть некоторые недостатки; это усложняет API и вводит дополнительное состояние для объекта shutdown-but-valid.
Вместо этого рассмотрите возможность получения шага (3) для блокировки, пока все запросы не будут выполнены. Есть компромиссы ...