![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Здравствуйте...сам чую, то что я сейчас скажу попахивает маразмом, но все же спросить не помешает..
Есть класс CTclWrapperBase, в нем виртуальные функции... Кто то другой (CChertEgoZnaetChto) наследует и добавляет свою (virtual void SomeFunction), вызывает мою функцию RegisterTclFunction я делаю там всяческие преобразования..храню адрес его функции в каком нибудь массиве, это не важно...теперь вопрос Возможно ли...чтобы я из своей функции класса TclWrapperBase зная что создан обьект типа CChertEgoZnaetChto вызвал SomeFunction зная только ее адрес, и параметры которые автор класса CChertEgoZnaetChto мне каким то образом передаст.. Вобщем точно что то из мира фантастики, но может хоть как то можно пройтись циклом по виртуальной таблице? В принципе проблем бы не было еслибы все функции написанные другими имели один и тот же формат, т.е. принимали одинаковые параметры, но как то не хочется их заставлять...проблема только с параметрами Добавлено @ 14:33 Если хотя бы у кого нибудь есть документация о том как работает виртуальная таблица, где взять ее адрес и как с ней работать...тоже сойдет |
|||
|
||||
| Royan |
|
|||
|
Dreamer ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1708 Регистрация: 14.9.2002 Где: Лондон Репутация: нет Всего: 15 |
Это зависит от компилятора. Например, в VС++ есть специальный указатель __vfptr. Его можно только похачить чтобы получить адрес виртуальной функции так не доберешься. Но эти хаки все очень не желательны, ибо можно всю таблицу виртуальных функций испортить. Опять же возвращаясь в __vfptr, ее адрес как я понимаю (но может быть и ошибаюсь) можно выскоблить только путем асмовской вставки из ЦПП такое не сделать. -------------------- Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь |
|||
|
||||
| Denn |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 6.8.2005 Репутация: нет Всего: 2 |
Насколько понимаю, именно на этапе компиляции неизвестно количество параметров. А что за функция SomeFunction()? У нее фиксированное или переменное количество параметров?
|
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Это не именно одна функция, просто пример...кто-то наследует мой класс, добавляет свои виртуальные функции, вызывает мою функцию RegisterTclFunction. Теперь нужно из базового класса вызвать правильную функцию...например, я написал
Если из TCL -а вызвать функцию my_function вызывается функция базового класса cmd_proc. И cmd_proc должен решить какую именно виртуальную функцию своих потомков вызвать. Проблемы бы не было еслиб все функции имели одинаковый прототип...но никто этого гарантировать не сможет... |
|||
|
||||
| DeadSoul |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 1217 Регистрация: 25.9.2005 Где: Москва Репутация: 2 Всего: 11 |
azesmcar, у тебя там есть иерархия классов? Судя по всему есть раз используешь виртуальные функции.
Почитай про паттерн Посетитель(Visitor) P.S. К каким последствия приводит модификация таблицы виртуальных функций сказать не могу, но вряд ли к чему-то хорошему -------------------- Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". Бьем спамеров их же оружием. Пусть весь спам сыпется им [email protected] |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Почитаю, хотя подумал немного вижу другое решение, но для этого нужно кое что сделать...а вот как это сделать понятия не имею...
Как известно va_arg это макрос...аргумент ... тоже... Если сделать так чтобы все функции принимали параметр va_list а потом уже хотя бы вызовом одного макроса или функции распределить все параметры функции по полочкам...например
макрос GetTclParams должен сгенерировать код вроде param1 = va_arg( ap_list, int ); param2 = va_arg( ap_list, char ); Формат параметров допустим у меня есть... вопрос сводится к тому можно ли в С++ макросах писать циклы, или делать хоть какой то минимальный parsing? можно как то подумать над рекурсивными макросами но ANSI C++ их не поддерживает...могут возникнуть проблемы, не стоит.. |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Тогда уж не макрос, а шаблон(ы). Что-то вроде этого:
Но все это весьма и весьма unsafe... Никто не проверит, что для вызова нужной функции в стек положили нужные аргументы. ИМХО, использовать такой подход можно только где-то в глубине кода, причем закладка параметров в стек и их извлечение должны осуществляться в рамках одного класса/модуля. Кроме того, любая функция, вызываемая таким образом, нуждается в написании оболочки, которая будет извлекать для нее параметры из стека. Оно надо? Проще case написать по сигнатурам, как в MFC при диспетчеризации команд. Попробуй сформулировать задачу, что ты хочешь. Поройся в паттернах. Наверняка можно найти другое, более прозрачное и безопасное решение. -------------------- ... |
|||
|
||||
| Mad |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Эксперт Сообщений: 656 Регистрация: 18.10.2004 Где: Одесса Репутация: 7 Всего: 19 |
azesmcar
если у тебя есть формат параметров, то зачем так изгаляться ? а если список параметров выберается в дочернем классе, то откуда твой родительский класс будет знать какие именно значения в эти параметры ложить ? |
|||
|
||||
| azesmcar |
|
||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
От вызова дочерним классом функции RegisterTclFunction... Например так. RegisterTclFunction( interp, "test_function", "%s %d %c" ); Зарегистрирована Tcl функция которая принимает параметры типа %s %d %c всего три параметра.. будет осуществляться автоматическая проверка, при вводе менее трех параметров выдаваться на экран что то вроде help -a...и тому подобное...можно конечно чтобы все пользовательские функции принимали va_list но потом неудобно выковыривать из них параметры... типа этого.. int param1 = va_arg( ap, int ); int param2 = va_arg( ap, int ); ... char param20 = va_arg( ap, char ); можно это как то автоматизировать макросом, или чем нибудь другим..вот и весь вопрос...
Прелестно...ты представлешь приблизительно сколько страниц у меня будет занимать только обявления template -ов если вдруг юзеру заблагорассудиться (а ему наверняка заблагорассудится) написать функцию с приемом 20, 25 параметров... Добавлено @ 08:03 Я думаю что то вроде этого должно быть на ассемблере push param1 push param2 call function разумееться это не код а описание... |
||||
|
|||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
User'ов, которые пишут в C++ функции с 20 параметрами, нужно убивать в младенчестве.
Чтобы потом те, кто сопровождает их код, не чувствовали себя ассенизаторами. Но даже и 20 шаблонов прописать - за пол-часа управишься. Не все ли тебе равно, сколько там страниц будет? Ровно так и поступают, кстати, такие библиотеки как boost в аналогичных случаях (конечно, не извлечение параметров из стека имеется в виду). Хотя я лично ограничилась бы 5ю. Даже 3-мя. ИМХО, если у функции вдруг образовывается больше параметров, пора делать рефакторинг. Юзер получит ошибку компиляции и задумается, на фига ему столько параметров. Не на Фортране пишет. Но как я уже писала, это плохой способ, потому что небезопасный. Если нужно свести разнообразные события в одну точку вызова, способ один: упихать в какую-нибудь структуру типа Windows MSG. Или объявить что-то вроде интерфейса IData, и все передаваемые структуры данных от него наследовать. Все-таки подумай: действительно ли тебе нужно все вызовы делать из одной точки? Может, тебе нужно что-то вроде делегатов? Это сообщение отредактировал(а) Earnest - 3.10.2005, 20:45 -------------------- ... |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Это Tcl Wrapper, если каждый будет писать вызовы для себя то кому же он тогда нужен этот wrapper? Не знаю сколько юзеру захочеться написать параметров, но теоретически это возможно. и ограничивать возможности юзеров не очень то правильно...если теоретически ему захочется написать такую функцию он не сможет... Можно конечно еще там что нибудь надумать..но лучше всего было бы автоматизировать этот процесс...т.е. или его надо автоматизировать или этого класса вообще не будет.. |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |