![]() |
|
|
![]()
|
|
| Doga |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 115 Регистрация: 20.12.2007 Где: Россия, Обнинск Репутация: нет Всего: нет |
Всем привет.
Кто-нибудь знает конструкцию для С++ Builder , аналогичную нижеследующему выражению в Delphi? Например:
Данная конструкция, а именно "class helper for ", позволяет получить доступ к приватным членам класса в Delphi. Существует ли что-либо подобное для С++ Builder? Это сообщение отредактировал(а) Doga - 2.7.2015, 14:25 |
|||
|
||||
| rudolfninja |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 341 Регистрация: 19.2.2013 Где: г. Минск Репутация: нет Всего: 6 |
Привет.
Есть два способа: 1) Дружественные функции и классы. 2) Унаследоваться от нужного тебе класса и использовать свой класс. |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 26 Всего: 459 |
На самом деле нет ни одного аналогичного способа. Класс хелпер используется случае когда мы не имеем доступа к реализации или не хотим вмешиваться в работу класса написанного сторонним разработчиком. Класс хелпер не меняет ни длину объекта, ни таблицу VMT, ни RTTI. Просто возможность создать функции типа геттера или сттера не предусмотренные разработчиком. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| Doga |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 115 Регистрация: 20.12.2007 Где: Россия, Обнинск Репутация: нет Всего: нет |
Насколько мне известно, функцию (или класс) можно сделать дружественной какому-либо классу только при объявлении самого класса.
TCustomForm, к сожалению, уже объявлен. А наследники класса по определению не могут получить доступ к членам класса родителя, если те объявлены в секции private. Для того она и существует. Так что, оба этих способа не годятся. |
|||
|
||||
| rudolfninja |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 341 Регистрация: 19.2.2013 Где: г. Минск Репутация: нет Всего: 6 |
Да, что то я подумал, что они protected, не обратил внимание на слово "приватным". По поводу дружественного класса, я полагаю, у тебя ведь есть доступ к исходныму коду класса TCustomForm? Так почему бы не добавить туда класса друга или не переместить нужные методы в protected секцию? Нарушается инкапсуляция, но это не самое страшное. В прицнипе, получается, что мы вмешиваемся в работу класса, написанного сторонними разработчиками. Так, что, выходит, что Alexeis прав, аналогов нет. Это сообщение отредактировал(а) rudolfninja - 2.7.2015, 17:02 |
|||
|
||||
| Doga |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 115 Регистрация: 20.12.2007 Где: Россия, Обнинск Репутация: нет Всего: нет |
2rudolfninja
Эй! TCustomForm прямой родитель класса TForm ! Эти классы написаны не какими то сторонними разработчиками, а самим СОЗДАТЕЛЕМ! 2Alexeis Похоже, я не корректно сформулировал вопрос. Мне как раз и нужен класс хелпер, только для С++ Builder Если б я знал, как его использовать... Это сообщение отредактировал(а) Doga - 2.7.2015, 17:09 |
|||
|
||||
| rudolfninja |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 341 Регистрация: 19.2.2013 Где: г. Минск Репутация: нет Всего: 6 |
Вот нашел интересный способ получения доступа к приватным членам класса, я про такой не знал.
Но в твоем случае, это будет трудно. |
|||
|
||||
| Doga |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 115 Регистрация: 20.12.2007 Где: Россия, Обнинск Репутация: нет Всего: нет |
Фу - фу - фу! И зачем такое предлагать?
|
|||
|
||||
| rudolfninja |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 341 Регистрация: 19.2.2013 Где: г. Минск Репутация: нет Всего: 6 |
Как один из вариантов решения проблемы.
|
|||
|
||||
| Guinness |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 21.6.2009 Где: Зеленоград Репутация: нет Всего: 10 |
Нормальный вариант решения данной "проблемы". Правда, было бы лучше, если бы была указана причина, по которой необходимо получить доступ к приватным членам класса. Возможно, тут просто какие-то проблемы с пониманием работы класса, либо проблемы с архитектурой приложения, либо тот самый редкий случай, когда без этого не обойтись. Но тогда придётся пользоваться всякими низкоуровневыми возможностями языка. |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 26 Всего: 459 |
Можно кусочек кода написать на делфи, и включить в проект на С++ Builder. Проект С++ Builder допускает и паскалевские файлы. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| Doga |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 115 Регистрация: 20.12.2007 Где: Россия, Обнинск Репутация: нет Всего: нет |
Для простых классов, как в тех примерах, это, вполне возможно, и будет работать.
Кста, там упоминается о небезопасности и серьезных ограничениях возможностей этого способа. Однако. В общем случае, класс может содержать множество (в том числе и однотипных) элементов, и далеко не факт, что необходимый будет объявлен первым. Ладно, пока это не проблема - идём дальше. Пусть нужный нам класс является наследником другого класса, который также является наследником уже своего родителя, и т.д.. В итоге, наш класс может быть наследником длинной цепочки предков, каждый из которых, в свою очередь, может обладать нетривиальной структурой. Какой адрес, с каким смещением, какое выравнивание надо будет использовать для получения доступа к нужному элементу, применяя предложенный способ? Даже если получить доступ к этому элементу удастся (предположим, удалось одурачить компилятор и вычислить? (подобрать!) смещение), можно ли будет перенести такой код в другую версию компилятора (IDE) без изменений? Или опять танцы с бубном? Короче, этот способ не переносим и не безопасен. Я бы согласился на такое только от безысходности, и то не факт... Теперь расскажу что мне было нужно. Нужно чтобы клиентское окно MDI приложения не рисовало вогнутую (lowered) рамку, когда в нем не открыто ни одно дочернее окно или когда их свойство WindowStete != wsMaximized. Судя по исходникам Forms.pas, необходимо перехватить обработку системного сообщения 0x3F (я не знаю, что это такое). В этом месте можно отключить отрисовку этой рамки. Но, чтобы всё было корректно, перед отключением рамки не плохо было бы вызвать штатную оконную процедуру(хотя и без неё вроде как работает). Так вот, в классе TCustomForm есть приватный член - void * FDefClientProc, являющийся указателем на ту самую оконную процедуру Клиентского окна главной формы MDI приложения. Рассмотрим теперь иерархию классов: TObject->TPersistent->TComponent->TControl->TWinControl->TScrollingWinControl->TCustomForm->TForm->TMyMDIForm. Таким образом, имеется экземпляр класса, 9-ый в цепочке наследников (TMyMDIForm), при этом нужно получить доступ к приватному элементу 7-го наследника(TCustomForm). Таким способом - не реально. В результате, написал класс-хелпер на паскале и подключил к проекту. Всё работает. Не понятно только, почему в Дельфи класс-хелпер есть, а в Билдере его нет? Это сообщение отредактировал(а) Doga - 3.7.2015, 16:30 |
|||
|
||||
| Doga |
|
||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 115 Регистрация: 20.12.2007 Где: Россия, Обнинск Репутация: нет Всего: нет |
Модуль FormHelper.pas
FormHelper.hpp (хидер) для FormHelper.pas, генерируется автоматически:
Использование:
Перегруженный ClientWndProc:
Полагаю, этим, практически штатным способом, можно получить доступ к любым приватным данным класса. По крайней мере в границах VCL Это сообщение отредактировал(а) Doga - 6.7.2015, 11:49 |
||||||||
|
|||||||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 26 Всего: 459 |
Побуду немного в роли КЭПа. Наверное потому что это разные языки. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| Doga |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 115 Регистрация: 20.12.2007 Где: Россия, Обнинск Репутация: нет Всего: нет |
Это для меня не новость, однако, компилятор у них один - это то, как раз, на мысль и наводит...
С точки зрения программиста на С++, чувствуешь себя немного обделённым, по сравнению с пользователями Дельфи :( Это сообщение отредактировал(а) Doga - 6.7.2015, 15:37 |
|||
|
||||
![]()
|
| Правила форума "С++ Builder" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C++ Builder | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |