![]() |
|
Модераторы: bsa |
![]()
|
|
| SABROG |
|
||||||||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
У меня около 30 обычных функций с одной и той же сигнатурой, но разным поведением. Есть общая функция в которую поступает структура, где одно из полей типа int state. В зависимости от этого state я вызываю одну из 30 функций. Писать switch() с 30 case'ами не хочется. Что остается, массив с хендлерами (callback'ами)
? Если будут варианты, то хотелось бы на чистом C++ с/без stl. Boost и tr1 не предлагайте, пожалуйста. --- Есть такая глупость:
Сделал, чтобы не приходилось в нескольких методах создавать временную переменную, которая передается в другую функцию:
При таком объявлении:
--- В случае с классом вместо структуры мне достаточно вызвать метод так:
Как вы могли заметить дизайн структуры гораздо проще и читабельней, но в случае с ней приходится писать много лишнего потом. Вопрос в том, возможно ли инициализировать переменные-члены структуры нулями во время передачи её в качестве default-constructed argument для метода класса? Что-то типа этого:
|
||||||||||||
|
|||||||||||||
| djamshud |
|
|||
![]() Пердупержденный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 23.11.2009 Репутация: 4 Всего: 39 |
Если я правильно понял суть сего длинного поста... В структуре можно сделать конструктор и написать в нем:
Таким образом по умолчанию в в функцию попадет структура, инициализированная нулями. -------------------- 'Cuz I never walk away from what I know is right Alice Cooper - Freedom |
|||
|
||||
| SABROG |
|
||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
По этому поводу такой комментарий встретил:
|
||||||
|
|||||||
| djamshud |
|
|||
![]() Пердупержденный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 23.11.2009 Репутация: 4 Всего: 39 |
Там про классы написано с виртуальными методами и сложными данными внутри, как я понял. Структуре с членами-интами и прочими POD-типами ничего не станет, как я считаю, по крайней мере сам применял такой подход неоднократно, и проблем не было.
ЗЫ. Да и классам с таблицей виртуальных функций, но с простыми POD-членами, тоже ничего не станет, т.к. те компиляторы, что я я видел, отделяют данные от всего прочего и указать на объект фактически является указателем на поле данных объекта. Добавлено через 6 минут Ну и в догонку, писать больше, но проблем с "плохой инициализацией" не будет:
-------------------- 'Cuz I never walk away from what I know is right Alice Cooper - Freedom |
|||
|
||||
| KOHCEPBATOP |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 21.4.2010 Репутация: 1 Всего: 1 |
Если очень боязно, можно сделать так:
|
||||
|
|||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
SABROG
может так? Это сообщение отредактировал(а) azesmcar - 30.4.2010, 12:56 |
|||
|
||||
| SABROG |
|
||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Разве стандарт гарантирует, что все значения будут инициализированы нулями?
А этот вариант интересен. Я правильно логику понимаю, тут происходит Си cast безымянного set'a (?) с целочисленными значениями к MyStruct? Аналогично:
Тогда странно, что такие варианты не работают:
Это сообщение отредактировал(а) SABROG - 30.4.2010, 13:46 |
||||||
|
|||||||
| djamshud |
|
|||
![]() Пердупержденный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 23.11.2009 Репутация: 4 Всего: 39 |
SABROG, ага. Только не знаю, как правильно называется этот безымянный сет, не силен в теории. Вспомнил о нем, так как иногда применяю, когда нужно передать в функцию некоторую структуру, а отдельной строкой (и переменной!) инициализировать ее не хочется.
-------------------- 'Cuz I never walk away from what I know is right Alice Cooper - Freedom |
|||
|
||||
| djamshud |
|
|||
![]() Пердупержденный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 23.11.2009 Репутация: 4 Всего: 39 |
Удалено по причине: копия
Это сообщение отредактировал(а) djamshud - 30.4.2010, 13:46 -------------------- 'Cuz I never walk away from what I know is right Alice Cooper - Freedom |
|||
|
||||
| KOHCEPBATOP |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 21.4.2010 Репутация: 1 Всего: 1 |
||||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Похоже это называется анонимной структурой, и с ней похоже тоже не все так гладко: http://stackoverflow.com/questions/177393/...-structure-in-c
|
|||
|
||||
| mes |
|
||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
ну это смотря кого инициализировать.. может и не нулем не аналогично.. только константной ссылке можно присваивать временный рвалуе объект.. Добавлено через 4 минуты и 17 секунд
отличная аргументация
а вот хотелось бы поподробней узнать, что имелось ввиду.. Это сообщение отредактировал(а) mes - 30.4.2010, 13:52 |
||||||
|
|||||||
| djamshud |
|
|||
![]() Пердупержденный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 23.11.2009 Репутация: 4 Всего: 39 |
>http://stackoverflow.com
Проблема их была в том, что структура была размером в 4 мегабайта и стэк заканчивался из-за ее копии. >( struct bigstruct ){ 0 } Тут надежда, что компилятор поймет, что всю структуру нужно инициализовать нулем, а компилятор, как я понимаю, делать этого не обязан. При явном перечислении членов структуры проблемы нет. -------------------- 'Cuz I never walk away from what I know is right Alice Cooper - Freedom |
|||
|
||||
| SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Значит gcc 4.4.1 не следует стандарту? Все компилится и работает без константности.
По иронии название их сайта совпадает с проблемой Ясно. Значит правила все-таки есть. Инициализировать каждый член по отдельности. Добавлять ключевое слово "struct", чтобы оставить совместимость с языком Cи. Осталось понять насчет константности ссылки и почему static_cast'ом нельзя привести безымянную структуру к нужному типу. По второму вопросу, с хэндлерами, есть мысли? |
||||
|
|||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
||||
|
||||
| djamshud |
|
|||
![]() Пердупержденный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 23.11.2009 Репутация: 4 Всего: 39 |
>отличная аргументация
Не аргументация, а поправка. >а вот хотелось бы поподробней узнать, что имелось ввиду.. С виртуальными функциями я погорячился. А имелось в виду:
Но это уже хаки, на них рассчитывать не нужно, конечно. >По второму вопросу, с хэндлерами, есть мысли? Вами же предложенный массив, чем не решение? -------------------- 'Cuz I never walk away from what I know is right Alice Cooper - Freedom |
|||
|
||||
| azesmcar |
|
||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
Это сообщение отредактировал(а) azesmcar - 30.4.2010, 14:36 |
||||
|
|||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Ага, значит, если типы в структуре Plain Old Data (POD - int, char и т.д.), то они должны автоматически инициализироваться нулями. Значит в моем случае следующий код сделает всё сам:
Да какое-то он в стиле Си. Я конечно ничего против языка Си не имею, но думал, может функторы какие-нибудь применить можно, классы, stl. Это сообщение отредактировал(а) SABROG - 30.4.2010, 14:55 |
|||
|
||||
| mes |
|
||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
почему здесь нельзя инизиализировать ссылку значением понятно ? ну а константную можно, и сделано для того, чтоб можно было, в частности :
Добавлено через 42 секунды |
||||||
|
|||||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Об этом я знал, просто меня удивил твой комментарий насчет "не эквивалентности". Я ведь о другой эквивалентности говорил, о приведении (объявлении?) безымянной структуры к нужному типу или нужного типа, а не о правах доступа/свойстве объекта. Я так до сих пор в этом не разобрался, что там происходит "(int){0}" толи объявление, толи приведение. Это сообщение отредактировал(а) SABROG - 30.4.2010, 15:02 |
|||
|
||||
| azesmcar |
|
||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
SABROG
Да, впрочем к агрегатам (?) можно и такой способ применить
можешь тут почитать, тоже доп. информация. http://forum.vingrad.ru/forum/topic-257566...y1856934/0.html |
||||
|
|||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
У меня ситуация несколько иная, есть несколько функций, где идет вызов другой функции, в которую нужно передать структуру инициализированную нулями. Поэтому я хотел от такого избавиться:
|
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
ну или с default значением, но это только для POD структур. а зачем нужны несколько функций, которые делают тоже самое? Это сообщение отредактировал(а) azesmcar - 30.4.2010, 15:27 |
|||
|
||||
| mes |
|
||||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
ну так мой комментарий относился к слову "аналогично", которое в свою очередь относилось к строке
т.е. я подчеркнул , что она не аналогична
{0,0} - не есть безымянная структура, и создать объект без указания типа по такому определению не получится. о правах доступа в этой теме вообще никто не говорил
создание безымянной структуры инициализированной списком параметров, но, на сколько я знаю, такой подход нежелателен по стандарту.. |
||||||||
|
|||||||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
MyClass ведь не POD тип? Но член member все-равно будет проиницилизирован нулем, так как он POD? Функция принимает в качестве параметров структуру с указателями на callback функции для установки перехватчика. Иногда есть необходимость снимать ранее установленые перехватчики, чтобы вызывался оригинальный хендлер, для того, чтобы избежать рекурсии. Можно конечно написать новую функцию типа uninstallFilter(). Но я решил вместо этого вызывать функцию типа setFilter() без параметров, чтобы снять ранее установленные обработчики. Пока подержу тему открытой, нужны мысли по поводу массива хэндлеров. Неужели это единственно верный и самый компактный вариант? |
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
ну так Вы столько воды в этой теме налили, что в ее расплывах и не видно где у Вас проблема то.. Добавлено через 2 минуты и 52 секунды
а чем виртуальные функции не угодили то ? Добавлено через 4 минуты и 7 секунд
тут не понятно о чем Вы.. отдалено предполагаю, что хандлер при вызове сам устанавливает хандлеры.. Это сообщение отредактировал(а) mes - 30.4.2010, 15:50 |
||||
|
|||||
| azesmcar |
|
||||||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
нет, не будет.
можно проверить
Добавлено через 3 минуты и 23 секунды откровенно говоря я не совсем понял суть задачи, если можно глобальнее и подробнее. |
||||||||
|
|||||||||
| SABROG |
|
||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Если брать вопрос про инициализацию структуры нулевыми значениями, то проблема в читабельности кода. Подход с классом выглядит не читабельно и громоздко по сравнению со структурой с 4мя указателями. Функция библиотеки (не моей) принимает в качестве аргумента структуру в которой нужно передать 4 указателя на обычные статические функции. Я не могу этого изменить, но могу обернуть этот вызов в свои функции.
Чего-то я запутался Короче речь о const-correctness, уж не знаю как это правильно перевести. Ага, то есть еще одна дверь закрывается и остается полагаться на default constructed value для POD типов или как более универсальный, но слишком громоздкий и нечитабельный вариант с классом как в первом моем посте. Не заморачивайся, у меня самого сейчас та еще каша в голове. Просто даже по логике необходимость подготавливать аргумент, значение которого заранее известно, в функцию или метод кажется не совсем правильной. Зачем писать лишний код где-то отдельно, если можно поставить значение по умолчанию или инициализировать структуру сразу при вызове функции?
ОС присылает int'овые состояния, которых больше 30, на кажое состояние отдельные функции, которые запрашивают от ОС дополнительную информацию о них у той же ОС. Вот я и не хочу делать 30 и более case'ов. А это уже проблема. Значит между этими двумя вариантами большая разница:
Я правильно понял? Это сообщение отредактировал(а) SABROG - 30.4.2010, 16:42 |
||||||
|
|||||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
нет, на самом деле между классом и структурой только одна разница, по умолчанию все члены класса являются private и наследование по умолчанию от класс - private. Все остальное тоже самое. В примере выше проблема не в использовании ключевого слова class, а в приватности члена класса. map или массив+указатель на функцию. А причем тут инициализация структур? Это сообщение отредактировал(а) azesmcar - 30.4.2010, 16:48 |
|||
|
||||
| SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Значит тут такая ситуация?
Так чтоль? Я уже путаюсь о чем вы меня спрашиваете. |
||||
|
|||||
| azesmcar |
|
||||||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
почти это POD структура, все нормально. это не POD структура и не агрегат, поскольку агрегатом является класс/структура/юнион, не имеющий нестатических private или protected членов (и еще куча всяких "если"), а POD структура является агрегатом, которая к тому же имеет еще несколько условий. Инициализацию типа
можно применять к агрегатам (ну и соответственно к POD структурам), а default initialization работает только на POD структурах, т.е. к примеру если мы напишем деструктор
этот код уже инициализировать нулями не будет
зато этот - будет, так как структура все еще является агрегатом.
Добавлено через 1 минуту и 51 секунду а тут поскольку MyClass не POD структура - default инициализация работать не будет, это значит что не будет работать совсем и оба члена останутся не инициализированными. Добавлено через 8 минут и 20 секунд я хочу понять задачу целиком, так как мы сейчас говорим о решении локальной проблемы инициализации структур, в то время как возможно это на самом деле и не нужно и задачу можно решить как-то иначе. |
||||||||
|
|||||||||
| mes |
|
||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
Так это Вы знаете, что у Вас имеется, а нам даете кучу Ваших размышлений и почти никакой сути задачи.
уже хоть что то.. Вы имеете ввиду различие в наличие/отсутсвии конструктора ? ну если проблема в читабельности, то ловите такой вариант :
Это сообщение отредактировал(а) mes - 30.4.2010, 17:32 |
||||||
|
|||||||
| SABROG |
|
||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Представь черную коробку, на которой написано "OS", коробка принимает структуру из четырех членов - указателей. Если указатели нулевые, то установленные пользовательские обработчики заменяются на системные. Ну и как я уже несколько раз выше писал хочется такого:
Но без такого По крайней мере теперь понятно, что такое:
Можно использовать безопасно, но как сказал mes, он где-то видел, что этого делать не рекомендуется. А вот в случае с классами лучше такого вообще не делать, так как редко когда будут соблюдены все условия, чтобы инициализация нулем работала. Постоянно висящая переменная плюс новая функция - обертка. Переменная NullCallbackList будет так и так каждый раз копироваться на стек. Мой вариант мне уже не кажется таким уж плохим:
Наличие конструктора, как я понимаю, превращает MyClass в не POD тип. |
||||||
|
|||||||
| mes |
|
||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
пока не взяли адрес, ее можно считать (при включенной оптимизации) не существующей.. Где функция обертка ? Unregister ? так она лишь для демонстрации, и применена на основании Ваших же примеров.
А когда передается параметром по умолчанию в стек разве не копируется ? Добавлено через 5 минут и 15 секунд "Это " для читабельности.. для Вашей структуры вполне достаточно инициализации обычным способом
если SetHandler ваша, то
хотя, имхо, с Null... именно для читабельности, а также для самоконтроля, лучше .. |
||||||
|
|||||||
| SABROG |
|
||||||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Preambulus:
Прошу менять простить, если в ближайшие часы, я буду беспредельничать и говорить глупости. Пятница и я немного нетрезв. Ambulus:
Типу NULL я никогда не доверял. Но я не ошибся, ты имеешь ввиду такую конструкцию?
(надеюсь тебя не коробит то, что я пробелы убираю перед скобками и перед перечислениями параметров. Пока я не нашел веских аргументов в пользу этого стиля. Читабельность на мой взгляд не меняется)
С этим я согласен. Только еще с тех времен, когда я писал на ассемблере, premature optimisation засело в голову.
Копируется конечно. В моем случае оно просто копируется, а в твоем оно копируется, да еще и висеть член NullCallbackList остается в памяти, это если без оптимизации, хотя согласен, аргумент не убедительный, но не доверяю я ей. Думается мне, что лишний раз лучше не провоцировать компилятор на оптимизацию. Таким?
А в своем коде, если бы эта пара строк встречалась хотябы 3 раза, ты бы так и оставил или все-таки сделал класс? |
||||||||||
|
|||||||||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
SABROG
Мне немного не нравиться то, что если завтра обработчиков понадобиться больше - то придется добавлять новые аргументы. Может сделать как-то так?
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
ну если плыть по этому руслу, то "оболочка" SetHandler лишняя, MyClass может успешно справиться самостоятельно.. |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
||||
|
||||
| SABROG |
|
||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
В моем случае те константы, которые я использую не менялись в течении 15 лет (так как часть кода я тырю из утилиты, которой именно столько и новых констант я не увидел в современной ОС с последними апдейтами). К тому же я использую некоторые "хаки", которые буквально через месяц возможно не будут работать (а у меня выбора нет, публичного API предоставляющего такие возможности у библиотеки нет). Но в целом твоя идея правильная. Просто разницы особой не будет:
P.S.: проплюсовал трёх человек по разным причинам. azesmcar - я тебе написал в комменте "за идеи", а сейчас подумал и решил, что скорее за "конкретику", очень уж мне понравились цитаты из стандарта. Это сообщение отредактировал(а) SABROG - 30.4.2010, 20:36 |
||||||
|
|||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
|
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
mes
Понятно, ну тогда еще что-то такое
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Я смотрю вы там между собой чего-то уже проектировать начали
Нет, это уже другой вопрос совсем. Те 4 каллбэка остаются как и были, их количество неизменно. А эти 30 каллбэков это уже реакция всего-лишь на один каллбэк, который принимает в себе эвент от ОС, который может принимать выше 30 состояний. Это сообщение отредактировал(а) SABROG - 30.4.2010, 20:46 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
ага.. главное что не будет лишнего "мазолевания" глаз. |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
к новой клавиатуре привыкаю, так что не удивляйся если сейчас еще и после проектировки начну код писать. надо же попрактиковаться, а то две строки 5 минут набираю
если что-то глобально - никакой разницы оформлено это в виде синглтона или нет, по мне так даже лучше в виде синглтона. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
синглетон не суть, он только для удобства представления мысли.. интуитивно, так как вы до сих пор не огласили задание, наследование не очень хорошее решение.. оставляете снаружи старые грабли.. ну так видите сколько нужного Вы держали в секрете Добавлено через 3 минуты и 8 секунд тогда не пойму что мы всю тему обсуждали, если у Вас каллбяки один раз подключились и один раз отключились ?! Добавлено через 4 минуты и 41 секунду Вы уж простите меня как топик_стартер, но я выступаю за то, чтоб считать тему не законченной и ожидаю подробностей задачи. |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
||||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Как вы могли догадываться всё дело пишется на Qt. Наследование не отъемлемая часть, я наследуюсь от QApplication. 4 callback'а это функции типа: beforeSignal, afterSignal, beforeSlot, afterSlot. Это дело не документировано, но работает. То есть тут я устанавливаю фильтра вообще на все сигналы и слоты (такой стандартной возможности в Qt нет, максимум QSignalSpy, которому обязательно нужен конкретный объект и конкретный сигнал. Этим дело не ограничивается и я позарился фильтровать все события приходящие от ОС (WM_* - windows, XEvent - X11). C Windows проблем небыло, есть специальная функция, которая все разбирает и возвращает отладочную информацию в виде строки. С XEvent уже проблемка, в Qt нет нигде формирования отладочной информацией и мне пришлось брать исходники старой утилиты xev, которая написана на Cи и всё переписывать на C++/Qt. Конечная цель заключается в написании класса на базе QApplication, которая выводит 3 уровня событий: OS (WM_*, X11, Мака нет, так что не судьба), QEvent'ы, Signals and Slots. Способы все это сделать найдены после штудирования исходников Qt, осталось переписать xev с Си на C++. Если всё получится, то выложу на каком-нибудь форуме по Qt в качестве класса для отладки событий приложения, ну и в академическо-образовательных целях. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
1. Вы устанавливает свой фильтр вместо фильтра приложения.
2. Там Вы отлавливаете XEvent и в зависимости от него вызываете, я так понимаю, один из системных методов приложения. теперь где возникла проблема ? в пункте один никакого многоразового использования структуры нет, а к пункту два это структура никоим образом не относится... Добавлено через 7 минут и 5 секунд хочу также обратить внимание на то, что наследование нужно лишь для выполнения одной части работы, а и имено для подключения системы фильтрации.. Сама же обработка событий желательно должна быть описана в другом классе. |
|||
|
||||
| SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Проблем с реализацией нет. Я изначально вопрос поставил в контексте "правильного стиля программирования". Это не совсем так. Дело в том, что qDebug() внутри себя содержит объект QTextStream на базе QObject'a и только в деструкторе выводится сообщение в консоль. Разрушаемый QObject шлет сигнал destroyed() после каждого вызова qDebug(), появляется рекурсия, которая неизбежно приводит к крашу. Мне просто необходимо снимать свой фильтр событий перед выводом в консоль, а затем ставить его снова. Но это уже давно не проблема. Я создал глобальную копию QTextStream и отказался от всех вкусносней перегрузки оператора << в qDebug(), а в деструкторе QApplication вызываю снятие фильтра, чтобы программа не крашилась при выходе.
Дело в том, что система фильтрации требует в качестве фильтруемой функции - статическую функцию. Что мне остается? Создавать синглтон или по копии некоторого класса в каждой из, эмм 5 функций (4 на каллбэки сигналов, 1 на фильтр QEvent'ов). Но даже если описать обработчики событий в качестве методов. Их будет больше 30 или один огромный switch() case. |
||||
|
|||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
Рискуя нарваться на фразу из первого поста "буст не предлагать" все же предложу boost::bind в крайнем случае можно написать что-то свое, специфическое. Это сообщение отредактировал(а) azesmcar - 30.4.2010, 22:07 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
две функции Register и Unregister или одна с флагом и опять же никакого множественного использования структуры.. Добавлено через 54 секунды нда.. помойму Вы не через окно, а через форточку пытаетесь пролезть.. |
|||
|
||||
| SABROG |
|
||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
По идее тут можно обойтись и стандартным std::bind1st(std::mem_fun(&MyClass::myMethod), pointerToMyClassExemplar). Но что в итоге мне это даст, класс с теми же 30 методами-хендлерами? Даже для Unregister требуется передать всю ту же структуру с нулевыми значениями в указателях. Какая разница будет это обертка типа:
или
Мне необходимо контролировать жизнь глобального объекта (потому, что я использую функции вместо методов) и жизнь глобального объекта заканчивается после деструктора экземпляра класса QApplication. Это сообщение отредактировал(а) SABROG - 30.4.2010, 22:20 |
||||||
|
|||||||
| mes |
|
||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
"описать обработчики" и "будет свитч" между собой не связаны.. повторюсь, помойму Вы перенамутили.. Добавлено @ 22:20 "заступлюсь" за тс в этом случае, так как никакой динамики требущей бинда тут нет.. Добавлено @ 22:21
Ну так может прежде Вы нам ответите на вопрос, как ваши 30 хандлеров связаны с регистрацией фильтра ? Это сообщение отредактировал(а) mes - 30.4.2010, 22:21 |
||||||
|
|||||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Тогда давайте вернемся к черной коробке с именем (OS). Есть одна функция (свой фильтр), которая принимает эвент от ОС. Количество возможных состояний в эвенте больше 30 и нужно каждое из них обработать. Как поступить? Здоровенный switch() case с >30 вариантами, который по размеру будет как весь код утилиты xev или 30 обработчиков? |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
давайте.. Пока не понятно по какому принципу связан евент и 30 вариантов. По имени, числовой константе, зависит от состояния звезд statemachine или иначе ? если связь прямая, то через отражение на словарь, для порядковых констант - линейный вектор, а для не порядковых и имен map и т.д ну и все таки какя взаимосвязь хоть через switch , хоть без него ?! Это сообщение отредактировал(а) mes - 30.4.2010, 22:32 |
|||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
То ли я уже нажрался в хлам, то ли просто не могу тебя понять. Эвент - структура, в структуре есть int поле, которое может принимать 30 и более значений состояния, все имена состояний описаны в системном хедере линукса. Я их всех undef'нул и создал свой enum с такими же именами, а благодаря метаобъектной системе у этого enum'a еще и появился массив текстовых названий каждого члена перечисления. В общем от числа (int) зависит то какой обработчик я запущу и то, что я буду спрашивать у ОС о дополнительной информации именно этого числового значения.
Массив имен есть (static const char* []), значения констант есть (int), имена есть (MyEnum::myName1). Чего не хватает, того массива с адресами обработчиков в первом посте? Тоже есть. Но правильно ли это? Структура, где были 4 указателя это для сигналов и слотов. Тут всё очень просто, никаких состояний нет. Тут как бы вопрос закрыт, я понял, что шел правильным путем, только сам язык C++ немного расстроил, пришлось написать больше, чем хотелось бы. Затем идет второй вопрос с хэндлерами. Это уже тема отдельная, тут ставится всего-лишь один фильтр через передачу адреса на статический метод. Проблема в организации системы обработки этих событий внутри обычной статической функции. Либо писать портянку, либо обрабатывать каждое состояние еще в >30 отдельных функциях. Но ИМХО быстрей получить указатель на функцию через индекс, чем делать >30 сравнений с нужным состоянием. Это сообщение отредактировал(а) SABROG - 30.4.2010, 22:43 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
обьект может сам этим заниматься.. разницы нет функции или функции-члены
не требуется.. Register и Unregister статические функции члены класса, также как и саллбяки фильтрации. |
|||
|
||||
| SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Конечно может. Только если он решит, что должен уничтожаться до деструктора моего класса - будет проблема. Ну разница обычно в том, что статические функции-члены не имеют доступа к членам класса в отличае от методов. Конечно можно приводить qApp к моему классу, чтобы получить указатель на объект класса.
Но это же еще одна функция. Не лучше ли просто передать аргумент по умолчанию инициализированный нулевыми значениями? Хотя с unregister() повышается читабельность кода, тут надо подумать, что мне важнее, понимать код через пару лет или искать комментария по коду и в голове прокручивать логику. |
||||
|
|||||
| mes |
|
||||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
Ну мне откуда должно быть это известно, что там у Вас, если Вы этого не говорили ? тем более что мы не в ветке линукса сидим Терь знаем.. значит удобно отразить на вектор. оистался вопрос вектор чего.. Вот это опять вода.. суть порядковые они или нет ?
и это вполне можно было опустить ) исходя из того как я понял представленное, не очень. Добавлено через 6 минут и 41 секунду
мм.. кто он ? зачем ? статические функции фильтра адресуют вызов методу обработчика, который представлен например статической переменной.. Добавлено через 12 минут и 59 секунд да, только не функция, а статическая функция-член
не лучше, так как как можно выделить как единицу логики - как регистрировать фильтр лучше всего знает фильтр.. вам же нужно не произвольный набор колбяков регистровать, а именно фильтр. |
||||||||
|
|||||||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Если бы я знал значение слова "порядковый", то сказал бы. Могу сказать, что числа идут неразрывно от нуля до >30, то есть если делать i++, то будет последовательный перебор всех состояний.
Нуу, эмм, советуйте как правильней... |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
приведенные пункты не противоречат друг друга.. Т.е. чем луше читабельность, тем меньше напрягов с комментами и логикой. Добавлено через 1 минуту и 25 секунд
сорри, я перепутал "порядковыйй" с "последовательным". Добавлено через 2 минуты и 10 секунд хэндлер может быть выражен как методом, так и объектом. Добавлено через 5 минут и 29 секунд вектор, в контексте темы, это не std::vector, a любое линейно представленный контейнер, в том числе и обычный массив. Добавлено через 7 минут и 1 секунду ну так пытаюсь, но Вы так и не ответили как связан хэндлер и регистрация фильтра.. |
|||
|
||||
| SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 1 Всего: 91 |
Объект.
То есть мне нужно 30 статических переменных, которые будут предоставлять метод для обработки состояний? А какому классу она должна принадлежать, QApplication?
Согласен. Сделаю Register и Unregister. Если объектом считать указатель на функцию, то смысла добавлять её в вектор не вижу. Если объектом считать некий класс, который будет предоставлять перегруженный оператор (), то объявлять >30 классов не хотелось бы. |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
если объектом считать объект класса представляющий общий интерфейс (т.е в контексте обсуждения, наследованным от базового класса с виртуальными функциями). оператор () или нет тут совсем не важно. под вектором подразумевается так же и тот же самый си-массив. тут больше не от вашего желания зависит,а от постановки задачи.. В одном случае удобнее выразить методами, а в другом легче через классы.. Добавлено @ 23:43 нет.. не стоит впадать в крайности.. достаточно и одной. Добавлено через 3 минуты и 58 секунд тут зависит от Вас.. правильнее выразить через отдельный класс, но если лень и MyApplicatioн чист, то можно и в нем напрямую. Добавлено через 5 минут и 58 секунд могу набросать схему кода, если ответите на мой неоднакратно поставленный вопрос, как хэндлер связан с регистацией фильтра ? а также что должно быть на выходе хэндлера ? в чем выражается его работа ? Это сообщение отредактировал(а) mes - 30.4.2010, 23:43 |
|||
|
||||
| azesmcar |
|
||||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
не совсем понял причем тут динамика? Ну это может быть не байнд а
в принципе да, вполне можно обойтись без boost::bind, вот набросал пример. Я не успеваю за вами все читать, так что извините если мой пост устареет к тому времени
Это сообщение отредактировал(а) azesmcar - 1.5.2010, 08:26 |
||||||
|
|||||||
| mes |
|
||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
если б тс нужен был сервис, к которому можно было подключить любой обработчик, то да буст::функтион и буст::бинд были бы хорошим вариантом.. однако тс не хочет лишних расходов, и все что должно подключиться заранее известно.
также мы выяснили, что ид эвентов последовательны, и вместо мап вполне подходит линейный контейнер (и тс отдает предпочтение статическому константному масиву).
ну вот я как раз и рассказал, основное, что смоглось выясниться у тс. |
||||||
|
|||||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |