Недавно начал писать на Qt более или менее серьезное приложение. И сразу возникла проблема.
Есть у меня класс TcpLinkManager. Он содержит член QTcpSocket. В TcpLinkManager есть методы-слоты, которые реагируют на события connect/disconnect, идущие от QTcpSocket. И есть ещё один класс Log. Когда происходят события разрыва/установки соединения из класса TcpLinkManager вызываются методы Log, которые должны делать запись в лог. Экземпляры TcpLinkManager и Log сделаны ввиде глобальных переменных. И они видят друг-друга.
Когда я закрывю приложение, то наблюдается следующая картина:
- Вызывается деструктор глобальной переменной Log::~Log(). Объект Log уничтожен.
- Вызывается деструктор глобальной переменной TcpLinkManager::~TcpLinkManager(). Вызывается деструктор QTcpSocket. Он закрывает сокет и выбрасывает сигнал в метод-слот TcpLinkManager. Тот пытается вызвать метод объекта Log для записи сообщения. Но объект Log уже уничтожен.
- Segmentation fault....
Раньше я не сталкивался с подобными случаями. И не задумывался о таких вещах. Привык, что деструкторы уничтожают объект и не вызывают кучу сторонних методов с неожиданными сайд-эффектами. Я решил проблему добавлением в код TcpLinkManager::~TcpLinkManager() вызова метода .blockSignals(true) для экземпляра QTcpSocket. Но такое решение мне не нравится. Хочется так писать код, чтобы не задумываться о том, в какой последовательности будут уничтожаться объекты.
Вопрос: Какой есть способ «красиво» решить проблему? Как пишут те, кто много работает с Qt?