![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Ivan. |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
Здравствуйте коллеги.
Уже несколько лет я возвращаюсь к мысли как же все таки реализовать проперти в сях. Все время упираюсь во всяческие ограничения компиляторов и т.п. и вот наконец решил, может не самый идеальный вариант, но все же не плохой. ЗАДАЧА: Основная задача - это уйти от всяческих конструкторов, дополнительных переменных и максимально оптимизировать код на скорость, объем и удобство применения и вот что у меня получилось: 1. Оптимизация - здесь все отлично, оптимизируется все на этапе компиляции и при работе ни чем не отличается от прямого доступа; 2. Применение - здесь тоже не плохо, можно прикреплять что угодно, хоть к полю родителя, хоть проперти на проперти, да хоть самого на себя зациклить можно; 3. Описание - здесь чуть похуже, но все равно не плохо: а) необходимость прописать класс хозяина или мутатора. б) разные дефайны для описания нужного проперти. А в остальном не больше чем в настоящем __property; 4. Память - так как мой проперти является структурой, а многие компиляторы описывают пустую структуру минимум в один байт, то каждое проперти будет занимать по 1 байту. Эту проблему я решил описанием всех пропертей в union, то есть в худшем случаи все протепря займут в сумме 1 байт в классе; 5. Ну и наконец сама реализация - всего 15 строчек дефайнов. КОД:
ОПИСАНИЕ: PROPERTY_BEGIN - начало блока пропертей. PROPERTY_END - конец блока пропертей. Объявление проперти: PROPERTY_GS - с getter-ом и setter-ом PROPERTY_GW - с getter-ом и прямым доступом записи в поле PROPERTY_RS - с прямым доступом чтения поля и setter-ом PROPERTY_RW - с прямым доступом чтения поля и прямым доступом записи в поле PROPERTY_G - только с getter-ом PROPERTY_R - только с прямым доступом на чтение PROPERTY_S - только с setter-ом PROPERTY_W - только с прямым доступом на запись остальные дефайны служебные ПРИМЕР ПРИМЕНЕНИЯ:
ВЫВОДЫ: Как видите привязаться можно к чему угодно, хоть к проперти родителя и оптимизируется на ура. Если обнаружите ошибки или новые идеи - пишите. Это сообщение отредактировал(а) Ivan. - 24.8.2011, 16:36 -------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
||||
|
|||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
инициатива не должна быть наказуема! поэтому держи пять
но давайте лучше посмотрим на препроцессированный код:
|
|||
|
||||
| Ivan. |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
и что в нем не то? ну раскрыл ты дефайны, тебя это пугает? в итоге при компиляции это все сводится к нулю
-------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
меня ничего не пугает. смотрю и думаю...
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
что привлекло с беглого взгляда: попробуйте наследоваться от вашего класса с пропертями множественным наследованием, при этом Ваш класс должен быть не первым.. Это сообщение отредактировал(а) mes - 18.8.2011, 20:04 |
|||
|
||||
| Ivan. |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
хотел проверить, но еще не успел. также нужно сделать проперти [] и закрыть операторы копии
-------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
|||
|
||||
| Ivan. |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
Результат: в Tclass1::Ffoo = 1 (так как переменная volatile) в Tclass1::Ffoo = 3 в Tclass2::Ffoo = 4 Действие t.foo2 = 2; пропустил за ненадобностью, потому что оно тут же перекроется новыми значениями 4. Вывод: с множественным наследованием работает прекрасно -------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
|||
|
||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 7 Всего: 50 |
А в бусте что нет пропертей?
|
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Более того, в свое время Борланд пыталась их пропихнуть в стандарт. Но не приняли.
|
|||
|
||||
| Ivan. |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
ни как не могу придумать реализацию проперти с индексом.
идея такая:
остается вопрос, как передать Index? Это сообщение отредактировал(а) Ivan. - 21.8.2011, 19:19 -------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
может так ?
|
|||
|
||||
| Ivan. |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
интересно, но это уже не проперти, если вместо [] придется использовать (), и все равно не получится реализовать сеттер
-------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
ну так поставьте оператор [] Добавлено @ 21:20 сейчас подумаю.. Добавлено @ 21:24 вам надо возвращать не ссылку на _Val , а временный прокси-объект хранящий индекс в себе Это сообщение отредактировал(а) mes - 21.8.2011, 21:24 |
|||
|
||||
| Ivan. |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
придумал:
раскрою дефайны, чтобы было понятней:
в итоге опять же все оптимизируется на этапе компиляции и ни чем не отличается от прямого вызова мутаторов. Это сообщение отредактировал(а) Ivan. - 22.8.2011, 11:11 -------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
||||
|
|||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 7 Всего: 50 |
Было бы неплохо убрать PROPERTY_BEGIN и PROPERTY_END:
Это сообщение отредактировал(а) Alca - 22.8.2011, 12:09 |
|||
|
||||
| Ivan. |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
не получается по следующим причинам: 1. пустая структура во многих компиляторах равна 1 байту. (100 пропертей займет 100 байт в классе). для этого все проперти объединены в union. 2. нельзя получить относительный адрес объекта внутри объявления этого объекта. для этого в начало union-на помещена структура с именем __PROP, по которой определяется смещение родителя от проперти. Добавлено через 1 минуту и 30 секунд еще ни как не могу вспомнить флаг компилятора позволяющий преобразовывать указатель метода к void*, чтобы уйти от статических мутаторов -------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
||||
|
||||
| Ivan. |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
да, я понимаю. по этому такой флаг есть не во всех архитектурах. в билдере это не актуально, так как там есть настоящий проперти, в IAR_ARM указатель на метод равен 8 байтам, а вот в WIN_AVR такой флаг есть и указатель на метод равен указателю на данные. -------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
|||
|
||||
| Ivan. |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
вот что получилось на данный момент:
-------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
|||
|
||||
| Ivan. |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
Выяснилось, что описывать статические мутаторы не нужно. видимо когда я пытался решить эту задачу через темплейты я уперся в это ограничение и подумал, что это засада, а при реализации через дефайны в этом необходимость отпала.
ИТОГО все свелось к следующему:
Примет:
При рассмотрении ассемблера: В поле t.FVal помещено значение 1; Действие t.Val2 = t.Val1; было проигнорировано, так как это копирование самого себя, а переменная не является volatile; Действие t.Array[10] = t.Val3; было проигнорировано, так как Index лежит за пределами массива FArray; В PORTB выдан 0, так как по условию, если Index лежит за пределами массива - getter возвращает 0. Остались следующие неудобства: - необходимость описывать блок пропертей; - разные дефайны для описания разных пропертей; - и необходимость описывать название класса хозяина проперти. Это сообщение отредактировал(а) Ivan. - 24.8.2011, 17:07 -------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
а что заменить это внутренним тайпдефом разве не получается ? |
|||
|
||||
| Ivan. |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
приведи пример пожалуйста. что то в голову ничего не идет -------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
что то типа :
Это сообщение отредактировал(а) mes - 24.8.2011, 19:37 |
|||
|
||||
| Ivan. |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
ну то есть вынести в объявление блока пропертей - логично
-------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
|||
|
||||
| Ivan. |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
обновленный вариант:
пример:
-------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
||||
|
|||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
Ivan., я так понял, что при использовании проперти совместно с массивами, без гетера и сетера не обойтись?
Добавлено через 5 минут и 15 секунд думаю, что все же нужна возможность использовать проперти совместно с массивами но без гетера и сетера. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
при использовании type_traits и SFINAE, вместо макросов: PROPERTY_GS, PROPERTY_GW, PROPERTY_RS, PROPERTY_RW, PROPERTY_G, PROPERTY_R, PROPERTY_S, PROPERTY_W, PROPERTY_IGS, осталось бы всего два: PROPERTY_GET и PROPERTY_SET. которые были бы применимы как к членам-данным включая массивы, так и к сетерам/гетерам.
Это сообщение отредактировал(а) boostcoder - 10.9.2011, 12:35 |
|||
|
||||
| Ivan. |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
я долго пытался решить эту задачу с помощью template, я бы даже сказал, не один год.
вот так вот спишь ночью и вдруг приходит сонная мысль - "вот же оно решение!, в теории все должно работать". просыпаешься, начинаешь реализовывать и опять та же самая непреодолимая стена. дело в том, что определение смещения поля от корня класса:
-------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
|||
|
||||
| Ivan. |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
да вроде бы есть уже:
вот с сочетанием [геттера или сеттера] и прямого обращения - тут немного сложнее. Добавлено через 6 минут и 47 секунд даже я бы сказал, что лучше вот так:
-------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
||||
|
|||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |