C ++: обратные вызовы и события системного таймера во время каскада деструкторов - PullRequest
1 голос
/ 22 ноября 2010

Предположим, что объектно-ориентированный проект предполагает, что объекты вызывают друг друга, и через некоторое время вызываемые объекты вызывают обратные вызовы инициирующих объектов (вызовы и обратные вызовы).Есть ли какое-то обещание, что при нормальном завершении программы при вызове деструкторов никакие системные таймеры не будут вызываться, и ни один объект не будет инициировать обратный вызов?

Ответы [ 4 ]

2 голосов
/ 22 ноября 2010

Существует довольно классная библиотека для обработки вызовов такого рода, и, конечно, это Boost.

Вот Boost.Signals2 , с гарантией корректности даже в многопоточных приложениях:)

Обратите внимание, в частности, на использование класса boost::trackable, поэтому уничтожение объектов автоматически делает недействительными вызовы до того, как они произойдут.

Примечание: Boost.Signals (его предок) имеет почти те же функции, но не поточнобезопасен

2 голосов
/ 22 ноября 2010

Нет, такой гарантии нет.

Вам необходимо написать свой код так, чтобы объекты не уничтожались до тех пор, пока вы не закончили их использовать.

1 голос
/ 22 ноября 2010

Нет, обещаний нет.

Есть два способа справиться с этим:

  • Имеют функцию отмены регистрации, которую объект может вызывать при уничтожении, которая гарантирует, что никакие обратные вызовы не будут вызваны после его завершения - CancelAllCallbacks() или аналогичное.

  • Иметь механизм слабой ссылки, такой как weak_ptr, который уже упоминался, для вызова обратного вызова, только если сильная ссылка была успешно получена.

Обычно первого варианта достаточно, если обратные вызовы не могут быть запланированы или вызваны асинхронно - тогда у вас нет синхронного способа предотвратить обратный вызов, который уже запланирован для вызова или фактически вызывается сейчас (или несколько инструкций с этого момента) в другой теме.

1 голос
/ 22 ноября 2010
  • boost's weak_ptr может помочь избежать доступа к разрушенным объектам из обратных вызовов вообще, так что, вероятно, также во время завершения.При использовании этого все объекты, которые необходимо вызвать обратно, нуждаются в таймерах shared_ptr.
  • , вызывающих функции / обратные вызовы, которые обычно являются библиотеками более высокого уровня, поэтому зависит от того, поддерживают ли они функцию stopAllTimers ().Если у вас есть контроль над библиотекой, ее, вероятно, не так сложно реализовать, но вам все равно нужно знать, когда ее запускать.
...