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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Издержки метообъектной информации.  (Прочитано 7191 раз)
SASA
Гость
« : Октябрь 09, 2008, 19:00 »

   Иногда я сталкиваюсь с такой проблемой при использовании connect( ): существование сигналов и слотов с соответствующими параметрами не проверятся на этапе компиляции. Поэтому, при изменении сигнатуры этих функций могут появиться скрытые ошибки. Я придумал такой выход:
Код:
Q_ASSERT(connect(obj1,SIGNAL(signal(int)),obj2,SLOT(slot(int))))
Это полностью не исключает ситуации описанной выше, но шансов "напороться" на эту ошибку становится больше.
Аналогично поступаю и с QMetaObject::invokeMethod().
Код:
Q_ASSERT(QMetaObject::invokeMethod(obj,"method",Q_ARG(QString,str))).
   При работе с проперти по имени (пример: obj.property("prop")) тоже может возникнуть ошибка при смене имени проперти или его типа. Поэтому для взятия значения я написал функцию, которая при отсутсвии свойства или неправельном типе вывалит ассерт. Вызов функции setProperty() тоже обкладываю ассертом.
   
   Собственно вопрос (или тема для дискуссии) А нормальное ли это решение? Может кто-то борется с этим по-другому.

P.S. Приветствую любые высказывания по теме.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #1 : Октябрь 09, 2008, 19:54 »

Очень интересное решение!
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Rcus
Гость
« Ответ #2 : Октябрь 09, 2008, 20:16 »

В релизном режиме макрос Q_ASSERT раскрывается в пустое выражение, поэтому скорее следует определить что-нибудь типа такого макроса
#ifdef QT_NO_DEBUG
#define CUSTOM_ASSERT(x) x
#else
#define CUSTOM_ASSERT(x) Q_ASSERT(x)
#endif
Записан
Alex03
Гость
« Ответ #3 : Октябрь 10, 2008, 08:39 »

А зачем всё это?
В дебаге connect() и так матерится в отладочную консоль.
Записан
ритт
Гость
« Ответ #4 : Октябрь 10, 2008, 08:43 »

в релизе - тоже )
Записан
Rcus
Гость
« Ответ #5 : Октябрь 10, 2008, 08:54 »

connect() - пишет, invokeMethod() - нет, а проверять результат выполнения обеих операций надо, так не лучше ли делать это единообразно?
*shrug* у меня правда и вызовы QSqlQuery::exec() обернуты в макрос, выполняющий проверку возвращаемого результата и в случае ошибки выводящий Q_FUNC_INFO, текст запроса и boundValues
« Последнее редактирование: Октябрь 10, 2008, 09:07 от Rcus » Записан
ритт
Гость
« Ответ #6 : Октябрь 10, 2008, 09:22 »

а вот на _эти_ макросы я взглянул бы Улыбающийся
самому лениво коряжиться...
Записан
Rcus
Гость
« Ответ #7 : Октябрь 10, 2008, 09:44 »

Код:
#ifdef QT_NO_DEBUG
#define Q_EXEC(q) {q.exec();}
#else
#define Q_EXEC(q) { \
if (!q.exec()) \
{ \
QMap<QString,QVariant> bv = q.boundValues(); \
QString sbv; \
for(typeof(bv)::const_iterator i = bv.constBegin(); \
i != bv.constEnd(); ++i) \
sbv += i.key() + ":=" + i.value().toString() + "\n"; \
qFatal("Query failed in function:%s\ntext: '%s'\nboundValues:\n%s\nreason: '%s'", \
Q_FUNC_INFO, \
qPrintable(q.lastQuery()), \
qPrintable(sbv), \
qPrintable(q.lastError().text()) \
); \
} \
}
#endif
« Последнее редактирование: Октябрь 10, 2008, 09:51 от Rcus » Записан
ритт
Гость
« Ответ #8 : Октябрь 10, 2008, 10:24 »

о, классно...только я этот макрос лучше в отладочную QtSql запихну...не люблю свои сорцы замусоривать Улыбающийся
Записан
SASA
Гость
« Ответ #9 : Октябрь 10, 2008, 14:33 »

Цитировать
В релизном режиме макрос Q_ASSERT раскрывается в пустое выражение
Так эти макросы нужны, чтоб отлавливать ошибки (причём явно допущенные по недосмотру, или забывчивости) в дебаге. А если они попадут в релиз, то это косяк

Ступил Обеспокоенный
Цитировать
А зачем всё это?
В дебаге connect() и так матерится в отладочную консоль.

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

Цитировать
у меня правда и вызовы QSqlQuery::exec() обернуты в макрос,
Вопрос. А кто что ещё обкладывает макросами?
« Последнее редактирование: Октябрь 13, 2008, 19:15 от SASA » Записан
Rcus
Гость
« Ответ #10 : Октябрь 10, 2008, 15:07 »

Код:
inline void qt_noop() {}

Q_CORE_EXPORT void qt_assert(const char *assertion, const char *file, int line);

#if !defined(Q_ASSERT)
#  ifndef QT_NO_DEBUG
#    define Q_ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop())
#  else
#    define Q_ASSERT(cond) qt_noop()
#  endif
#endif
//из QtCore/qglobal.h
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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