Название: Нужен ли QPointer Отправлено: Rain от Февраль 17, 2009, 23:53 А зачем вообще нужен QPointer? Я так вот сразу, не могу придумать пример, где функциональность которую он предоставляет, была бы полезна. Пример из QAssistant это вообще антипаттерн, стратегия замалчивания ошибок.
Код: QPointer<QLabel> label = new QLabel; Получается, что признаком того, что метку нужно отобразить является её "созданность". Как-то странно... Можно ли QPointer использовать в качестве обычного "умного указателя"? В документации об этом ничего не скзаано... Код конструктора и деструктора уводит в незадокументированные недра QMetaObject... Название: Re: Нужен ли QPointer Отправлено: Dendy от Февраль 18, 2009, 01:30 Дизайн QObject предполагает что каждый экземпляр уникален, то-есть его нельзя скопировать, склонировать, а место вызова деструктора чётко определено программистом. Поэтому да, вы задаёте абсолютно корректный вопрос - а нужен ли тогда умный указатель для QObject, если точка вызова деструктора заранее известна. QPointer - скорее вспомогательный класс, или хак, когда проще построить неопределённый код, в котором могут быть несколько вызовов деструктора и заранее не знаешь какой именно будет вызван.
Например, в Qt можно встретить такую конструкцию: Код
То-есть на этапе дизайна метода doSomething() разработчик не знает заранее будет ли удалён обьект внутри сигнала. Моё мнение что наличие QPointer в коде свидетельствует о плохом дизайне программы. Использование же его вместо простого обнуления указателя - конечно вариант, но это способ для "ленивых" и совсем не то зачем QPointer предназначен. Название: Re: Нужен ли QPointer Отправлено: ритт от Февраль 18, 2009, 14:31 Dendy, на мой взгляд немного торопишься с выводами (про плохой дизайн). к примеру, вызывается меню тулбаттона: на время показа меню у баттона отключается свойство autoRepeat - т.о. исключается повторный вызов менюшки при удержании кнопки мыши (как вариант, нагрузка высокая и события не успевают отработать вовремя) - но свойство-то надо вернуть в исходное состояние после скрытия меню? а в слоте, ассоциированном с каким-то акшеном из этого меню может быть уничтожение данного тулбаттона (или его родителя, или вообще всего окна) - получается, что после скрытия меню кнопка уже не будет существовать, но попытается восстановить отключенное свойство autoRepeat. в таком случае QPointer приходит как спасение. я пытался придумать как бы в данном случае обойтись без него - на ум пришёл только сигнал destroyed, но тут сложности с областью видимости флага для последующей проверки...других вариантов не придумалось...
Название: Re: Нужен ли QPointer Отправлено: Dendy от Февраль 18, 2009, 16:23 Возможно это единственный случай когда стот использовать QPointer - при синхронном вызове чужого кода, при котором он может удалить источник сигнала. Корни этой проблемы тянутся из самого C++. Цепочка дестукторов идёт сверху вниз, от порождённого класса к базовому, и предназначена для уничтожения самого экземпляра класса. При этом логика уничтожения обьекта находится в самом деструкторе. То-есть мы не можем прочитать некий флаг был ли удалён обьект, так как самого обьекта уже нет, вот и приходится сохранять его через такой хак - во внешнем экземпляре QPointer.
Название: Re: Нужен ли QPointer Отправлено: ритт от Февраль 18, 2009, 16:43 но это ведь не говорит о плохом дизайне кутэ? :)
скорее, наоборот - кутэ позволяет красиво обойти такую некрасивую проблему, одновременно с тем предоставляя guarded object pointer "для ленивых" программистов, кому не очень-то хочется следить за собственными объектами... Название: Re: Нужен ли QPointer Отправлено: Dendy от Февраль 18, 2009, 18:11 Как справедливо было замечено топикстартером, ещё QPointer может потенциально прятать ошибки, если использовать его для мониторинга обьектов неизвестно откуда. Нарушается семантика процедурного стиля программирования, чем лучше лишний раз не злоупотреблять.
Название: Re: Нужен ли QPointer Отправлено: ритт от Февраль 18, 2009, 18:20 согласен. но всё же есть ряд случаев, в которых QPointer оказывается весьма полезным.
к примеру, в плагине я создаю объект и возвращаю его по запросу. специфика объекта предполагает, что он должен быть только один. но я ведь не могу контролировать цикл жизни объекта - после работы с ним его вполне могут уничтожить, а плагин так и будет возвращать указатель на давно уже умерший объект... раньше я хранил в плагине указатель на данный объект и при создании экземпляра соединял его destroyed с приватным слотом, обнулявший этот указатель. теперь имеется возможность избавиться от ненужного слота и уверенно возвращать данный указатель, если не 0, в противном случае просто создаю его заново - очень удобно. |