Russian Qt Forum
Ноябрь 26, 2024, 01:50 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Нужен ли QPointer  (Прочитано 11752 раз)
Rain
Гость
« : Февраль 17, 2009, 23:53 »

А зачем вообще нужен QPointer? Я так вот сразу, не могу придумать пример, где функциональность которую он предоставляет, была бы полезна. Пример из QAssistant это вообще антипаттерн, стратегия замалчивания ошибок.

Код:
QPointer<QLabel> label = new QLabel;
label->setText("&Status:");
...
if (label)
label->show();

Получается, что признаком того, что метку нужно отобразить является её "созданность". Как-то странно...

Можно ли QPointer использовать в качестве обычного "умного указателя"? В документации об этом ничего не скзаано...
Код конструктора и деструктора уводит в незадокументированные недра QMetaObject...



Записан
Dendy
Гость
« Ответ #1 : Февраль 18, 2009, 01:30 »

Дизайн QObject предполагает что каждый экземпляр уникален, то-есть его нельзя скопировать, склонировать, а место вызова деструктора чётко определено программистом. Поэтому да, вы задаёте абсолютно корректный вопрос - а нужен ли тогда умный указатель для QObject, если точка вызова деструктора заранее известна. QPointer - скорее вспомогательный класс, или хак, когда проще построить неопределённый код, в котором могут быть несколько вызовов деструктора и заранее не знаешь какой именно будет вызван.

Например, в Qt можно встретить такую конструкцию:

Код
C++ (Qt)
void QSomeObject::doSomehing()
{
 QPointer pointer( this );
 emit someSignal();
 if ( !pointer )
   return;
 ...
}

То-есть на этапе дизайна метода doSomething() разработчик не знает заранее будет ли удалён обьект внутри сигнала. Моё мнение что наличие QPointer в коде свидетельствует о плохом дизайне программы. Использование же его вместо простого обнуления указателя - конечно вариант, но это способ для "ленивых" и совсем не то зачем QPointer предназначен.
Записан
ритт
Гость
« Ответ #2 : Февраль 18, 2009, 14:31 »

Dendy, на мой взгляд немного торопишься с выводами (про плохой дизайн). к примеру, вызывается меню тулбаттона: на время показа меню у баттона отключается свойство autoRepeat - т.о. исключается повторный вызов менюшки при удержании кнопки мыши (как вариант, нагрузка высокая и события не успевают отработать вовремя) - но свойство-то надо вернуть в исходное состояние после скрытия меню? а в слоте, ассоциированном с каким-то акшеном из этого меню может быть уничтожение данного тулбаттона (или его родителя, или вообще всего окна) - получается, что после скрытия меню кнопка уже не будет существовать, но попытается восстановить отключенное свойство autoRepeat. в таком случае QPointer приходит как спасение. я пытался придумать как бы в данном случае обойтись без него - на ум пришёл только сигнал destroyed, но тут сложности с областью видимости флага для последующей проверки...других вариантов не придумалось...
Записан
Dendy
Гость
« Ответ #3 : Февраль 18, 2009, 16:23 »

Возможно это единственный случай когда стот использовать QPointer - при синхронном вызове чужого кода, при котором он может удалить источник сигнала. Корни этой проблемы тянутся из самого C++. Цепочка дестукторов идёт сверху вниз, от порождённого класса к базовому, и предназначена для уничтожения самого экземпляра класса. При этом логика уничтожения обьекта находится в самом деструкторе. То-есть мы не можем прочитать некий флаг был ли удалён обьект, так как самого обьекта уже нет, вот и приходится сохранять его через такой хак - во внешнем экземпляре QPointer.
Записан
ритт
Гость
« Ответ #4 : Февраль 18, 2009, 16:43 »

но это ведь не говорит о плохом дизайне кутэ? Улыбающийся
скорее, наоборот - кутэ позволяет красиво обойти такую некрасивую проблему, одновременно с тем предоставляя guarded object pointer "для ленивых" программистов, кому не очень-то хочется следить за собственными объектами...
Записан
Dendy
Гость
« Ответ #5 : Февраль 18, 2009, 18:11 »

Как справедливо было замечено топикстартером, ещё QPointer может потенциально прятать ошибки, если использовать его для мониторинга обьектов неизвестно откуда. Нарушается семантика процедурного стиля программирования, чем лучше лишний раз не злоупотреблять.
Записан
ритт
Гость
« Ответ #6 : Февраль 18, 2009, 18:20 »

согласен. но всё же есть ряд случаев, в которых QPointer оказывается весьма полезным.

к примеру, в плагине я создаю объект и возвращаю его по запросу. специфика объекта предполагает, что он должен быть только один. но я ведь не могу контролировать цикл жизни объекта - после работы с ним его вполне могут уничтожить, а плагин так и будет возвращать указатель на давно уже умерший объект...
раньше я хранил в плагине указатель на данный объект и при создании экземпляра соединял его destroyed с приватным слотом, обнулявший этот указатель. теперь имеется возможность избавиться от ненужного слота и уверенно возвращать данный указатель, если не 0, в противном случае просто создаю его заново - очень удобно.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.069 секунд. Запросов: 20.