Russian Qt Forum

Qt => Общие вопросы => Тема начата: Ground от Март 16, 2012, 11:06



Название: Вопрос по проектированию
Отправлено: Ground от Март 16, 2012, 11:06
Доброго времени суток!
Зашел в тупик, не могу придумать как решить проблему со связью объектов. У меня есть класс Class1 и Class2. Мне нужно из объектов класса Class1 обращаться к объектам Class2 и наоборот. Как эта проблема решается без использования слотов/сигналов и включения объектов одного класса в другой?
Код
C++ (Qt)
Class1 cls1;
Class2 cls2;
 

У меня был вариант, передавать в конструкторе указатели друг на друга, но как отслеживать корректность указателей при удалении одного из объектов?


Название: Re: Вопрос по проектированию
Отправлено: BRE от Март 16, 2012, 11:11
У меня был вариант, передавать в конструкторе указатели друг на друга, но как отслеживать корректность указателей при удалении одного из объектов?
1. С помощью умных указателей, например QWeakPointer.
2. Уничтожаемый объект в своем деструкторе "уведомляет" второй объект о своем разрушении (как это делают те же объекты-наследники QObject)


Название: Re: Вопрос по проектированию
Отправлено: Igors от Март 16, 2012, 11:18
Более капитальный вариант - хранить ссылки в виде ID. Требует гораздо больших усилий


Название: Re: Вопрос по проектированию
Отправлено: Ground от Март 16, 2012, 11:22
Более капитальный вариант - хранить ссылки в виде ID. Требует гораздо больших усилий
А можно поподробнее, где хранить, что хранить?


Название: Re: Вопрос по проектированию
Отправлено: Igors от Март 16, 2012, 11:40
А можно поподробнее, где хранить, что хранить?
Базовые классы выглядят напр так

Код
C++ (Qt)
typedef long long TID;
// потомки CReference  имеют уникальное ID
struct CReference {
 ...
 TID mID;
 
 static std::map <TID, CReference *> mMapID; // мапа ID - указатель
};
 
// др объекты могут хранить ID потомков CRefTarget  
struct CRefTarget  : virtual public CReference  {
 ...
};
 
// потомки CRefHandler могут хранить ID CRefTarget'ов  
struct CRefHandler : virtual public CReference  {
..
};
 


Название: Re: Вопрос по проектированию
Отправлено: QuAzI от Март 16, 2012, 12:12
И как примерно это работает?


Название: Re: Вопрос по проектированию
Отправлено: Igors от Март 16, 2012, 13:56
И как примерно это работает?
Если коротенько: имея ID ссылающийся получает указатель из мапы, и (если указатель не NULL) пользуется им и забывает. Опять нужен указатель - опять взял по ID.

Заметим что ссылающемуся лучше не хранить IDs в членах класса. Ссылка знает всех кто на нее сослался (опять-таки по ID), возникает интересная общность, напр удаляя объект можно послать сообщение(я) всем ссылающимся и.т.п.


Название: Re: Вопрос по проектированию
Отправлено: QuAzI от Март 16, 2012, 14:43
Но списочек то нам всё равно надо инициализировать и заполнять, что работёнки поприбавит. Не совсем по теме, но чем можно было бы например контролировать что проинициализирован приватный QSqlQuery *mainQuery ? Попытаться его всобачить как QSqlQuery *mainQuery = 0 не получается. Что-то такое видел, когда с Qxt ковырялся, там создавался свой экземпляр QxtApplication при DLL_PROCESS_ATTACH и при DLL_PROCESS_ATTACH делался сначала delete, потом указатель чётко занулялся. В итоге проверка вида if (mainApp) работала.


Название: Re: Вопрос по проектированию
Отправлено: mutineer от Март 16, 2012, 14:47
Не совсем по теме, но чем можно было бы например контролировать что проинициализирован приватный QSqlQuery *mainQuery ? Попытаться его всобачить как QSqlQuery *mainQuery = 0 не получается.

Занулить в конструкторе и затем занулять при удалении объекта