![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| vaddsm |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Есть идея, вызвать на выполнение определенный код, после инициализации экземпляра объекта (класса) в памяти, не используя, его конструктор.
Сразу не понятно, конкретно, о чем идет речь, по этому приведу пример.
В приведенном примере сразу после инициализации obj появится сообщение MessageBox. При этом конструктор класса TClass1 не задействован. Так вот хотелось бы выполнить подобное в рамках класса TClass1, да так чтобы код, например того же мессаджбокса мог оперировать с параметром. MessageBox(0,arg,”;)”,0); К сожалению, подобная конструкция в c++ не разрешена:
Есть ли другая возможность выполнить подобное? |
||||
|
|||||
| Fin |
|
|||
![]() Дракон->Спать(); ![]() ![]() Профиль Группа: Участник Сообщений: 687 Регистрация: 4.1.2006 Репутация: 3 Всего: 10 |
Почему ты уверен, что конструктор класса не задействован. При создании объекта, автоматически вызывается конструктор данного объекта. Спрячь конструктор в protected область в первом примере. Сразу получиш от компилятора кучу мата.
С++ не допускает иницилизирование переменных параметрами в объявлении класса. Выход из этой ситуации для тебя,
Это сообщение отредактировал(а) Fin - 6.9.2008, 02:06 -------------------- Пролетал мимо. |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Так, понятно, похоже я недостаточно ясно объясни, что собственно хочу сделать. Мне необходимо добиться того, чтобы конструктор класса TClass1 не был задействован, но при инициализации экземпляра класса TClass1 выполнился код (функция) с параметром. Как реализовать данное без параметра я описал в первом примере, про то, что второй пример синтаксически неверен, я тоже написал, но в нем отражена суть того, что я хочу видеть.
|
|||
|
||||
| Fin |
|
|||
![]() Дракон->Спать(); ![]() ![]() Профиль Группа: Участник Сообщений: 687 Регистрация: 4.1.2006 Репутация: 3 Всего: 10 |
vaddsm, От того, что ты хочеш видеть, не изменяет принципы работы ООП. И синтаксиса С++.
Сделай через статик. есть несколько минусов. Но жить будет. Если хочеш чесать левое ухо правой ногой.
Лучше опиши, зачем тебе это нужно, может быть есть другие и более стандартные пути решения твоей задачи. Чем придумывать разные хаки. Это сообщение отредактировал(а) Fin - 6.9.2008, 10:51 -------------------- Пролетал мимо. |
|||
|
||||
| mes |
|
||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Нельзя создать объект в С++, не задействовав конструктор. Если Вы не определяете конструктора, то это делает за Вас компилятор.
используйте список инициализации :
Это сообщение отредактировал(а) mes - 6.9.2008, 10:53 |
||||||
|
|||||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
||||
|
||||
| cutwater |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 592 Регистрация: 24.6.2008 Репутация: 1 Всего: 10 |
ЗЫ: Извините не удержался. |
|||
|
||||
| vaddsm |
|
||||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Ты это к чему сказал то? Разве из моего сообщения следует, что я хочу создать ОБЪЕКТ не задействовав в этом мероприятии его КОНСТРУКТОР. Прошу перед тем, как что либо писать, внимательно вникать в суть поставленной задачи. Еще раз! Мне надо выполнить код при создании объекта, но при этом недолжно быть явного использования конструктора.
Это тоже, явно противоречит тому, что я писал. Еще раз: не размещая кода в конструкторе. Пример:
Например в VCL есть подобная реализация, таблица регистрирующая функции-обработчики оконных сообщений.
Проблема, в том что, метод Dispatch применяется в самом классе в нужном месте и в нужное время. В моем случае я делаю произвольную надстройку на любой класс и он о моем подобии Dispatch ни сном не духом, по этому приходится прописывать вызов этого метода еще и в конструкторе класса, что не очень френдли-юзер. Как бы избавится от дополнительной писанины в конструкторе. Чтобы на этапе описания полей класса уже были созданы все условия для вызова метода. Рассмотрю любые идее и хаки в том числе, в силу того что моя надстройка собственно и есть грязный хак. 2vinter
А какие здесь противоречия? В первом представленном примере, как раз так и происходит, проблем только в том, что без параметра. Конструктор TClass1 явным образом не задействован а сообщение появляется (MessageBox). Это сообщение отредактировал(а) vaddsm - 6.9.2008, 14:27 |
||||||||||
|
|||||||||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
для этого у классов должен быть предок, конструктор которого и делает, что тебе надо (в данном случае вызывает Dispatch) Добавлено через 2 минуты и 46 секунд если в Dispatch нужен параметр, то у тебя 2 варианта 1. чтобы твой класс передавал что надо в вызове конструктора родителя 2. чтобы конструктор родителя использовал глобальную (можно статическую) переменную, в которую ты заранее должен записать нужное значение. а чтобы куда-то не знаю куда само передавалось что-то, не знаю что - так не бывает |
|||
|
||||
| vaddsm |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Что ж, проблеск понимания (Alek86) появился, и это замечательно!
Наличие такого исключается, необходима реализация для любого класса.
Что, куда, а самое главное для чего я знаю на 100% (а что, я где то дал повод в этом сомневаться?). Я не знаю пока только, как и возможно ли? Предлагаю рассмотреть, такой пример: В классе есть метод, необходимо его выполнить сразу после инициализации объекта в памяти, при этом конструктор класса должен оставаться незадействованным в вызове этого метода. |
||||
|
|||||
| Alek86 |
|
||||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
не выйдет я допишу с1.cpp
и все а если (чтобы побороть мой пример) хочешь извращаться, и делать подобные "фичи"
то (кроме того, что тебе нужна поддержка прекомпилед хедеров (она не везде есть)) пусть земля тебе будет пухом, ибо никто (включая тебя) потом твою прогу не поймет и выражения типа
прибереги, пожалуйста, для школьников. тут большинство людей намного больше тебя в С++ разбираются, и если, по-твоему, они говорят не о том, что тебе надо, то это ТЫ виноват, так как плохо объяснил иначе тебе просто накидают кучу минусов и, с мотря на твой рейт, никто тебе на форуме и пытаться помочь не будет |
||||||||
|
|||||||||
| vaddsm |
|
||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Alek86, прежде всего спасибо за желание помочь. Но как то ты агрессивно настроен, в словах проблеск понимания, имелось ввиду, что ты и есть тот самый проблеск, ведь до тебя в сути вопроса не разобрался никто. Так, что это скорее был комплимент. Затем, я бы не брался утверждать сразу, что знаю язык лучше тебя, так, как не видел твоего кода и с тобой лично не общался. По этому выражение “тут большинство людей намного больше тебя в С++ разбираются”, ты уж прости но звучит не очень зрело. Вопрос действительно на первый взгляд, касается основы основ, но это не говорит о том что его решение примитив.
Давай прекратим словесную перепалку, и вернемся к сути вопроса. Прежде всего, почему ты счел
станет граблями на пути реализации моей идеи. В документации я могу явно указать, что блок
Необходимо описать в protected секции класса. Тогда, правильное его применение будет иметь форму:
Другое дело, понуждать пользователя писать еще код в конструкторе
Это сообщение отредактировал(а) vaddsm - 6.9.2008, 15:38 |
||||||||
|
|||||||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
||||
|
||||
| vaddsm |
|
||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
2vinter. Эти цитаты я так понял, были взяты из этого предложения:
А где в нем собственно противоречие?
Конструктор явно не задействован:
А код всеже выполняется! (MessageBox)
Вот и я с такими мыслями пришел на форум, но сколько раз убеждался на практике, что нет ничего невозможного. Может все же можно пойти на хитрость? |
||||||||
|
|||||||||
| Fin |
|
|||
![]() Дракон->Спать(); ![]() ![]() Профиль Группа: Участник Сообщений: 687 Регистрация: 4.1.2006 Репутация: 3 Всего: 10 |
Вопрос остается в силе, Для чего данное действо вообше нужно?
-------------------- Пролетал мимо. |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
но задействован ;) попробуй на досуге задницей через форточку вылезти, стандартную форточку совестких домов при инициализации объекта выполняется только конструктор(конструктор копирования) и больше ничего. Все остальное надо вызывать отдельно, либо из самого конструктора. Можно конечно сделать класс обертку, через который будут созадваться все объекты. Так же этот класс будет выполнять некую функциональность при создании. Но это сильно ограничит параметаризаию создаваемых объектов. |
|||
|
||||
| vaddsm |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Тут ооочень из далека заходить надо, чтобы полностью вопрос раскрыть. Но можно и в кратце: Есть набор функций, которые реализуют некоторое преобразование полей класса, скажем изменяют поведение некоторых методов этого класса.
Например, установив служебное слово virtual перед методом void __fastcall Method1();, мы указываем компилятору, что необходимо сделать данную функцию виртуальной и внести ее в VMT, DYNAMIC соответственно в DMT. У меня реализовано некоторое подобие VMT, но методы заносятся туда не на стадии компиляции а уже в рантайме. Собственно, для функций, которые реализуют с методами класса, нужные мне действия я пишу удобный интерфейс. Чтобы, это было настоль же лаконично и просто, как поставит фразу virtual в начале метода. Не нагружать пользователя сложными конструкциями, которые нужно прописывать в различные области класса (в том числе в конструктор). Например так как я писал:
Но, пока не придумал варианта проще чем, еще и в конструктор вносить
P.S Предлагаю пока откинуть универсальные кроссплатформенные методы, если таких нет для решения данной задачи, и сосредоточить внимание на средах BCB и VS. Любые конструктивные идеи приветствуются! Это сообщение отредактировал(а) vaddsm - 6.9.2008, 18:24 |
||||
|
|||||
| mes |
|
||||||||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Не был задействован- означает не вызывается. Так что на ваш ответ могу ответить : прежде, чем спрашивать, сформулируйте нормально вопрос!
Вы наверно будете сильно удивлены, но в приведенном примере ни одна строчка не выполняется при инициализации. В том числе и метод Dispatch ().
Потому что задействован!!! конструктор по умолчанию Скорей всего можно.. если ясно сформулируете задачу, думаю, кто нибудь из форумчан подскажет Что скрыто тут ? :
Ну a если добавить в Ваш дефайн строчку добавляюшая в нужный класс регистратор(или другой вспомогательный объект) с конструктором по умолчанию ? Это сообщение отредактировал(а) mes - 6.9.2008, 18:44 |
||||||||||||
|
|||||||||||||
| vaddsm |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
mes
Вы наверно, будете еще больше удивлены обнаружив, в том посте, откуда вы взяли эти строчки, следующие слова: Проблема, в том что, метод Dispatch применяется в самом классе в нужном месте и в нужное время. В моем случае я делаю произвольную надстройку на любой класс и он, о моем подобии Dispatch ни сном не духом, по этому приходится прописывать вызов этого метода еще и в конструкторе… Мне даже обидно как-то, ведь я сам написал об этом подробно.
Ок, здесь действительно мои слова можно было понять не правильно. Сказав “Конструктор явно не задействован” я имел ввиду, что мы руками не прописываем сюда TClass1(){/*Ничего*/};. Хотя, компилятор, еще да точки /*Ничего*/ помещает инструкции вызывающие конструктор TClass2. А в котором, уже в свою очередь, следует код вызывающий MessageBox. |
||||||
|
|||||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Я расценил эти слова, что в Вашем коде надо прописывать вручную, а в VCL это делается автоматом. Но в примере не нашел ничего подобного. тем более что перед примером шла строчка :
тут по контексту возникает смысл, что регистрация происходит в момент инициализации.. Если Вы имели ввиду виртуальность Dispatch, (инициализацию указателя на VMT) то причем тут вобще VCL ? Это сообщение отредактировал(а) mes - 6.9.2008, 18:57 |
||||
|
|||||
| vaddsm |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
mes, все похоже, что Вы меня поняли. Искренне спаибо!
У меня так:
Проблема MSL_TABLE_INIT, приходится в конструктор класса помещать. P.S. Если после этого поста остаются еще вопросы, прошу задовать. Это сообщение отредактировал(а) vaddsm - 6.9.2008, 19:46 |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Вам необходим this для вашей таблицы либо косвенно (как у вас в примере), либо прямо.
"Автоматически"при инициализации его можно получить только в конструкторе, того объекта, методы которого вам нужно делегировать. ИМХО, решить задачу, не затрагивая конструктора, нереально. |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Мне кажется Вы не туда акцент поставили в вопросе.
В данном исполнении у Вас, основная загвоздка на мой взгляд не в использовании конструктора, а в том , что пользователь может забыть добавить нужную строчку, для инициализации. Чтоб избежать подобного, надо научить компилятор сообщать об этом. Поэтому предлагаю реализовать описание таблицы внутри вспомогательного класса, для инициалиции которого требуется this основного. Тогда даже если пользователь добавит несколько конструкторов к основному классу, то компилятор не позволит не проинициализировать таблицу. |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Абсолютно, точно. Можно, конечно и ваш вариант, если я его правильно понял. Давайте на практике рассмотрим (простенький пример), того, что именно Вы имеете ввиду. Предположим дан вспомогательный класс Tmsl, у него есть метод void __fastcall dosomestuff(LPVOID PointerTo_PrimaryClass_Member); Вызывая данный метод я произвожу действия над членами основного класса. И допустим, есть основной класс, назовем его TPrimaryClass. Из данных условий, как ваша идея должна быть выражена в коде? |
|||
|
||||
| Lazin |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
тем кто понял суть вопроса, расскажите в 2х словах...
вопрос поставлен не точно, что за метод, виртуальный, закрытый, статический... сразу напрашиваются два решения:
там где я работаю, за такой код могут и уволить... Это сообщение отредактировал(а) Lazin - 6.9.2008, 23:11 |
||||
|
|||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
задача: делегировать произвольные методы одного объекта объекту обработчику. Само делегирование проблем не вызывает. Вопрос как красиво оформить, чтоб клиент, мог интуитивно использовать библиотеку, и компилятор предупредил бы в случае ошибки/упущения. Добавлено @ 23:36
Не до конца понял, что имели тут ввиду. Как насчет такого? использование виртуальности для реализации callback'a
Это сообщение отредактировал(а) mes - 6.9.2008, 23:37 |
||||
|
|||||
| vaddsm |
|
||||||||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Возможно, оффтоп и все же, что не так в примере то? (в двух словах)
Есть класс, совершенно любой, со своим набором методов и свойств. И у нас есть универсальный инструмент (другой класс), совершающий действия над методами любого класса. Для этого инструмента надо написать удобный интерфейс. Пример, есть класс над которым совершается действо:
Применительно к нему, код выполняющий интерфейс для “Инструмента”, выглядит так:
Все замечательно, красиво, удобно, но приходится писать еще в конструктор:
А ооочень не хотелось бы. Пример дефайнов для TOOL_TABLE я выложил выше. Добавлено @ 23:46
Ну, ну нет не такая задача.
Вопрос, верный! Это сообщение отредактировал(а) vaddsm - 6.9.2008, 23:49 |
||||||||||||||
|
|||||||||||||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
ради бога
вот вам и вызов сразу после инициализации)) Это сообщение отредактировал(а) Lazin - 7.9.2008, 00:09 |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Хотел вам mes + поставить за огромное стремление помочь, но не дают пока это сделать, говорят постов мало.
mes, пока не то. По последнему посту есть вопросы? |
|||
|
||||
| mes |
|
||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Это сообщение отредактировал(а) mes - 7.9.2008, 00:01 |
||||||
|
|||||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Lazin, не то, не правильно Вам прояснил суть mes. Прочитайте мой последний пост, может, станет яснее. Дело в том что мой “инструмент” пользователь будет применять к своему MyClass, а как он у него объявлен, от какого класса унаследован, это сугубо его дело и я не хочу его как либо в этом ограничивать.
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
в Борланде Вы можете кстати описать указатель на метод с помощью __closure и на этом построить таблицу
Это сообщение отредактировал(а) mes - 7.9.2008, 00:12 |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Ван, момент, дайте дочитаю mes'a , пока не псте сообщений!
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
То есть Вы хотите чтоб любой пользовательский класс мог легко использовать свое тело для Библиотечного интерфейса. Процесс передачи реализации интерфейсу называется делегацией. Вы хотите своими макросами(или другими способами) упростить делегацию. Правильно ? помимо прямой делегации упомянутой в предыдущих примерах можно например использовать борландскую __closure, бустовые сигналы, библиотеку FastDelegate (http://www.rsdn.ru/article/cpp/fastdelegate.xml) , или Winnie.Closure (http://dobrokot.nm.ru/cpp/CppMethodsCallback.html) |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
хозяин - барин, я вам расхожую идиому привел, которая как раз и предназначена для диспетчеризации вызовов методов Добавлено через 12 секунд объекта |
|||
|
||||
| vaddsm |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Да.
Нет, речь не идет о делегации, вовсе. Там совершенно другие задачи. Мой макрос:
Работает с адресами любых методов. Да и причем здесь методы, буть тут хоть переменные, члены класса, не важно! MSL.ReplaceMethod может оставаться черным ящиком, в рамках, задачи. Предложеный вами метод, всеьма изящен, хоть и не помогает решить задачу о которой я говорю. Опять ведь приходиться таскать за собой ExampleCalss(int a): INIT_TABLE {} или INIT_TABLE_(ExampleCalss). Было бы класно, если после слова TOOL_TABLE_END, пользователь мог забыть, о том, что от него что-то требуется еще. |
||||||
|
|||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
ага, я уже писал Я лишь привел пример организации таблицы, который не компилится если забыли проинициализоровать. Добавлено @ 00:50 так механизм можете оставить свой спрятав весь механизм внутри вспомогательного класса по аналогии приведенных выше примеров или добавив dummy - инициализатор #define INITIATOR(Class) class Initiator { public: Initiator (Class *p) { p->Init(); } } m_Initiator; если этот макрос спрятать в макросах описания таблицы, то пользователь не сможет забыть проинициализировать вашу таблицу Это сообщение отредактировал(а) mes - 7.9.2008, 01:00 |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Mes, да все верно, Ваш пример отлично решит задачу о целостности конструкции, назавем ее так. Еще раз отмечу, что мне ооочень понравилось. Но я пока еще хочу поломать голову над тем, чтобы эту самую конструкцию окончить на слове TOOL_TABLE_END. Спасибо, за помощь! Плюс пока не могу поставить (постов мало).
Если у кого будут идеи в сторону "непрописывания" кода в конструктор, я буду рад! |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
а как библиотека использует TMethodSpliceInterface ?
Он автоматически регистрируется при создании, или это делается внешней функцией? |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Экземпляр такого объекта создается при инициализации в памяти экземпляра класса над которым мы собираемся производить действия. Это сообщение отредактировал(а) vaddsm - 7.9.2008, 02:13 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
то что создается объект MSL, я видел. Как библиотека управляет этим интерфейсом ? просто запрашивается этот интерфейс у хозяина или он должен быть где то зарегестрирован? |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Пускай вас не смущает присутствие в название слова Interface, на самом деле это не абстрактный класс. Это обычный класс содержащий несколько методов, в задачу которого входит принять передоваемые параметры, обработать их и передать в нужном формате на вход внешней функции описаной в lib. Вообщем класс это "обычный", нет нигде он не регистрируется.
Это сообщение отредактировал(а) vaddsm - 7.9.2008, 02:38 |
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Нисколько не пугает название этого слова. Вопрос как происходит вызов нужного метода этого класса ? ну, например, есть такое:
кто, когда и как получает указатель на MSL ? Это сообщение отредактировал(а) mes - 7.9.2008, 02:56 |
||||
|
|||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Я же написал TMethodSpliceInterface - не абстрактный класс. А вызов его методов осуществляется:
И только. На этом область применения его оканчивается. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
[color=silver]
сорри - ночь на дворе ) Ну а с примером Вы перемудрили Правильно ли я понял: 1. Посредством интерфейса MSL , мы можем управлять состоянием хозяина 2. MSL - предоставляет некий общий интерфейс 3. Вызов методов MSL происходят на стороне клиeнта удобным ему способом. Добавлено через 4 минуты и 57 секунд это принципиальная деталь, или просто вариант реализации? |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Сделал именно так, как хотел видеть. В BCB работает, сейчас еще в VS отладить осталось.
После такой вот строчки: TAnyClass *Inst = new TAnyClass(); Появляется MessageBox(0,"Action fired~!","Trick! ;)))",0); Решил интригу сделать |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
борланд позволяет так писать? ))) Это сообщение отредактировал(а) mes - 7.9.2008, 13:13 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
У меня нет вариантов как Вы добыли this от Inst по смещению метода (
Добавлено через 4 минуты и 4 секунды тут borland позволяет забыть "&" ? Это сообщение отредактировал(а) mes - 7.9.2008, 13:15 |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
а почему нет? с & и без него записи эквивалентны |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
не хотел-бы я этот код разбирать
Добавлено через 4 минуты и 43 секунды вообще это не правильно, нужно писать &ClassName::CallMethod но borland позволяет и так... Добавлено через 7 минут и 27 секунд вот то-же ошибка, указатель на функцию не обязан помещаться в DWORD Добавлено через 9 минут и 53 секунды в общем код в топку, то-же самое можно сделать красиво с помощью шаблонов... кстати интересно, что ты будешь делать, когда отладчик тебе покажет на ошибку в строке Добавлено через 12 минут и 1 секунду неужели этот код собрался без единого предупреждения.... если да, то фтопку борланд |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
это почему это? |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Я так до сих пор и не понял кто и как будет использовать интерфейс,
вот еще один основанный на догадках пример, без затрагивания конструктора. Таблица составляется на этапе компиляции. В момент создания объекта, никаких(за исключением предусмотренных компилятором, таких как смена указателя на VMT) действий производится не будет. Связывание интерфейса с реализацией происходит в момент запроса интерфейса. Никаких лишних переменных в класс хозяин не добавляется . (т.е реально использовать такой вид связывания для чистых абстракных класов) Естественно , что для удобного использования , можно скрыть все под макросами, как в вышеприведенных примерах.
Это сообщение отредактировал(а) mes - 7.9.2008, 14:39 |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
потому-что мы получаем указатель на функцию vs2005, позволяет делать только так |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
Lazin, если есть под рукой Страуструп специальное издание. Открой страницу 199.
макросам ON_WM_SOMETHING можно скормить как func так и &func, разницы не будет. Следовательно VS по баробану, ка ки должно быть. Добавлено через 29 секунд 2005 не помню, но в 2003 и 2008 точно можно. |
|||
|
||||
| vaddsm |
|
||||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Указатель на метод класса НИКОГДА не DWORD, если только он не static __stdcall А вот первые 4 байта, всегда адрес метода в памяти, затем, например this... Это уже зависит от того, какой это метод, но в данном случае, мы конкретно указали void __fastcall.
С чего ради?
Lazin, а ведь на прошлый пафос, вроде: За такой код меня бы уволили. Ты мне так и не ответил, почему? А сейчас опять необоснованно разбрасываешься словами, и уж тем более:
Ну так давай! Докажи что это не болтовня! Тайна конструктора TMyLib:
|
||||||||||
|
|||||||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
А нельзя ли расшифровать, что происходит в ассемблерной вставке ? |
|||
|
||||
| Lazin |
|
||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
ты что-то путаешь в коде который ты привел
ты используешь указатель на метод класса, при чем там this я не в курсе, но я точно знаю что любой указатель нельзя приводить к DWORD, так как указатель может быть и 8-ми байтовым (на 64х битных системах), а указатель на метод или функцию нельзя приводить даже к void* попробуй собрать и запустить свой код под em64t, узнаешь потому-что лень, потому-что выходные
по твоему это входит в противоречие с тем что я говорил? Здесь происходит вызов функции, но, где гарантия что lpfn нужно вызывать именно так, ведь в своем коде ты делаешь С-style cast и приводишь указатель на функцию к DWORD, и в принципе, туда можно передать любую функцию... в общем так не делают Добавлено через 2 минуты и 3 секунды просвети, что это такое? |
||||||||||
|
|||||||||||
| vaddsm |
|
||||||||||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Да канеш можно.
Прежде всего давайте рассмотри начало любой функции описанной средствами языка c++ в машинном коде:
Как известно, регистр ESP – это указатель на текущий адрес в стеке, тогда из приведенного примера однозначно следует, что начало каждой функции ознаменуется: 1. Сохранением в стек регистра EBP, содержащего адрес начала стека вызывающей функции. 2. Записью в регистр EBP, текущего адреса в стеке. Благодаря этому правилу мы всегда можем раскрутить стек и дойти до начала стека интересующей нас функции. В нашем случае крутить ) придется не долго. Но так, как для выполнения этой операции нам потребуется один регистр, необходимо позаботится о том, чтобы его первоначальное значение не было утеряно:
Далее, получим адрес начала стека конструктора класса TMyLib.
Так, как конструктор класса TMyLib вызывается из конструктора шаблонного класса TMyLibInterface, получим начало стека и этого конструктора.
Мы уже у цели, финишная прямая – получение адреса начала стека конструктора класса над которым производим действие, в данном случае, это TAnyClass.
Но в данном случае мы берем значение не из ячейки стека, в которой находится очередной EBP, а на 4 байта выше, именно туда функция – метод класса помещает указатель. А как по вашему работает отладчик, который всегда в Watches, вам покажет значения локальных переменных. Вот, например как сохраняет this, fastcall метод:
После приведенных инструкций, в EAX у нас содержится адрес экземпляра TAnyClass. Почему именно EAX, спросите вы, а все очень просто, функции скомпилированных по конвенции fastcall принимают указатель this именно в этом регистре. Адрес метода, который мы будем вызывать у нас уже есть, это lpfn. Не будет терять время даром, nop, nop, nop )). Вызываем:
Вот и все, теперь для чистоты эксперимента, вернем все туда, где оно и лежало.
Это сообщение отредактировал(а) vaddsm - 7.9.2008, 17:20 |
||||||||||||||||
|
|||||||||||||||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
я отвечу. 1. Куча макросов, код тяжело читать. 2. Код - костыль, не то что палтформо - а компиляторо зависим. 3. Мне сходу не понятно, что делает втой код, и не факт что я бы быстро вьехал, если бы не знал. Это показатель, для меня. Это сообщение отредактировал(а) vinter - 7.9.2008, 17:27 |
|||
|
||||
| vaddsm |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
БОГ МОЙ! Гуру c++! Как по вашему указатель на метод класса соотносится с экземпляром класса, такой указатель как минимум должен содержать this и адрес самого метода в памяти.
Еще раз, указатель на метод класса, как минимум 8 байт, он может быть и 12 и 16 байт. Одно остается неизменным, то, что, такая вот конструкция *(DWORD *)&lpfun, вернет нам только, 4 байта - адрес самого метода, в случае если метод объявлен void, vod __fastcall, void __stdcall и тд и тп. С 64x разрядными системами я не работал, по этому демогогии не будет, хотя и для этого случая можно предусмотреть отдельный дефайн.
Так надо, говорю же, дефайн в крайнем случае добавить один, а так в принципе, можно и в этой форме попробывать. |
||||||
|
|||||||
| Lazin |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
этот код выведет:
как видишь можно вызвать любой код, и это не сломается при переносе на другую платформу Это сообщение отредактировал(а) Lazin - 8.9.2008, 09:38 |
||||
|
|||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Эта фраза (уволили) относилась к другому коду, не к последней реализации. А из конструктивного хочу знать, где именно зависимость от компилятора (BCB - VS)? У кого VS под рукой, проверьте! Это сообщение отредактировал(а) vaddsm - 7.9.2008, 17:43 |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
то что ты описал относится не к указателю на метод, а к указателю на метод с модификатором __closure, тоесть это работает только с BCB для всех остальных компиляторов указатель на метод, это указатель на функцию, никакого this там не будет |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
__fastcall
|
|||
|
||||
| vaddsm |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Макросы, тотже код, читать тяжело с непривычке. Так, что это субъективно.
Тут я жду как он себя на VS проявит, пока нет под рукой этого компилятора. Будет результат, тогда и поговорим.
Тут я стобой и спорить не буду, для меня тоже показатель. Но в данном случае код достаточно снабдить и комментом. Добавлено @ 17:51 Сейчас с VS разберемся. Добавлено @ 17:54 Lazin, тот код что ты привел, он какое отношение к задаче имеет? Я уже устал повторять, задача не в том чтобы с делигатами работать было удобно. Задача сделать удобный интерфейс для библиотеки, в той форме, в которой я изначально показал. Добавлено @ 17:56 ПОГОДИТЕ! а что VS не поддерживает конвенцию __fastcall???? Если поддерживает, в чем ваши притензии к коду? Это сообщение отредактировал(а) vaddsm - 7.9.2008, 17:57 |
||||||
|
|||||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
в том, что он нерабочий жаль проверить нечем |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Lazin, у меня нет большого опыта, работы в VS среде, но ты берешся утверждать, что:
допустим, LPMF_CKINGFUNCTIONPTR - тип заведенный для хранения указателей на функцию член класса вида: void Function_ofF_RINGTYPE(void); тогда, LPMF_CKINGFUNCTIONPTR lpFun = (LPMF_CKINGFUNCTIONPTR)&SomeClass->Function_ofF_RINGTYPE; после этого lpFun не будет содержать никакой информаци о SomeClass???! Добавлено @ 18:14
У меня он работает при любых интересующих меня условиях, я его писал и проверял. Ты не проверял, но утверждаешь что он не рабочий. Говорить догмами по моему, это привилегия бога. Меня ооочень интересует конструктивная критика. Это сообщение отредактировал(а) vaddsm - 7.9.2008, 18:15 |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
поддерживает, но не так как BCB
|
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Добрался до VS, сейчас доработаю.
Добавлено через 1 минуту и 7 секунд Ага, vinter, вот это я и называю конструктивно, спасибо! |
|||
|
||||
| Lazin |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
lpFun не будет содержать никакой информации об экземпляре SomeClass, мало того LPMF_CKINGFUNCTIONPTR lpFun = (LPMF_CKINGFUNCTIONPTR)&SomeClass->Function_ofF_RINGTYPE не скомпилируется если имелось ввиду вот это LPMF_CKINGFUNCTIONPTR lpFun = &SomeClass::Function_ofF_RINGTYPE; то вызывать lpFun нужно будет не так, как это делается в builder, для методов с __closure:
а так как это делают в С++:
конструктивная критика: щито такое __fastcall (); в теле класа?
|
||||||||
|
|||||||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Итак, я в отладчике )! Насчет ecx, ваша, правда. push ebp, mov ebp, esp, как я и писал, все тоже. Смотрим дальше...
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
__fastcall это (компиляторозависимое) соглашение о вызове, указывающая компилятору, что некоторые из параметров будут будут переданы не через стек, а прямо через регистры Добавлено через 1 минуту и 8 секунд http://ru.wikipedia.org/wiki/%D0%A1%D0%BE%...%BE%D0%B2%D0%B0 Это сообщение отредактировал(а) mes - 7.9.2008, 18:51 |
|||
|
||||
| vinter |
|
||||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
не не ен, он имеет ввиду, что значит
если я правильно понял. ясен пень, это стандарные дейстивия, необходимые для возврата из процедуры. |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
оп я не на то ответил ) __fastcall () - насколько я понял это перегрузка оператора инициализации объекта в борланде. то есть new Class(); // <- вот тут вызывается.. Это сообщение отредактировал(а) mes - 7.9.2008, 19:12 |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Возможна реализация компилятора, в которой данне действия будут выполнятся иначе и тогда код в на таком компиляторе станет не деиспособен, вобщем то на VS он тоже пока не работает, но погодите еще немного, сейчас внесем необходимые инструкции . |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
||||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
естественно, () это необязательная добавка. Впервые слышу об операторах инициализации. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Ну вот судя по всему борланд и положил на нее глаз )) |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Таки уж и стандартные? Стандарт - это язык, а то как, тот или иной производитель компилятора, представляет его в машином коде, это сугубо его личное дело. Сделал реализацию совместимую с VS и BCB, сейчас код выложу. Да комиляторозависимо, но это всеголишь интерфес к библиотеке, сама либа представлена набором функций, и если пользователь не может в силу несовместимости пользоваться простой конструкций, он сможет работать с функциями напрямую. Это сообщение отредактировал(а) vaddsm - 7.9.2008, 20:45 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Стандарты бывают разные. В данном случае шла речь о стандарте соглашений вызова. тут немного замутняет картину то, что используется __fastcall - a oно компиляторозависимое соглашение. |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Ужос ___х!
|
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Точто могу сказать одно, на консрукторы в VS конвенции не распростроняются, что непеши всегда аргументы в стек, this в ecx.
Это сообщение отредактировал(а) vaddsm - 8.9.2008, 02:15 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Это сообщение отредактировал(а) mes - 8.9.2008, 02:54 |
|||
|
||||
| dumb |
|
||||||||||||||||||||
![]() sceloglauxalbifacies ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2929 Регистрация: 16.6.2006 Репутация: 8 Всего: 158 |
vaddsm, приведенный тобой кривой костыль не только непонятен/несопровождаем, но и зависим не только от компилятора, но и от опций, а именно: от stack frames и от оптимизации. выключи frames(а в release они по дефолту выключены) или включи оптимизацию - и аля-улю.
косяк, кстати:
как уже было упомянуто, формирование фрэймов в стэке зависит от опции(и от компилера).
в общем случае можно только отсчитать н-ное кол-во фрэймов, и понадеяться, что вызовы шли именно так, как предполагалось.
в данном случае никакой необходимости в этом нет.
...если отключена оптимизация. и это в билдере, не где-то. где-то будет еще веселей. "боги", "гуру"...
|
||||||||||||||||||||
|
|||||||||||||||||||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
dumb, Спасибо, сейчас по пунктам отработаю приведенные вами замечания!
Вот пример, у меня работает при любом виде конструктора TAnyClass в средах BCB и VS. С опциями оптимизации, я пока не проработал.
... TAnyClass *x = new TAnyClass(); Коменты будут. P.S Права на чтение сегмента памяти не выставил, в следующем варианте будут. Добавлено @ 04:44 В Борланде работает при любых опциях оптимизации. А в релизе пока нет. Это сообщение отредактировал(а) vaddsm - 8.9.2008, 04:48 |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
|
|||
|
||||
| Lazin |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
блин, так и не понял, зачем пихать ук. на функцию в DWORD?
вместо
вполне прокатит
ведь ты вегда вызываешь один и тот-же метод в конструкторе, кстати, что будет, если пользователь в своем классе, захочет создать ф-ю с именем CallMethod? Добавлено через 1 минуту и 39 секунд
|
||||||
|
|||||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Lazin, CallMethod где? ГИДЕ? Он в TAnyClass, а ты this передаеш какой? На TMyLibInterface.
Это пример, в реали этот метод будет называться, где-то так: void hey_guy_do_never_try_to_name_method_like_this_f_king_long_method_name(void); Короч, универсального решения той задачи, которую я ставил изначально нет, есть частные вполне рабочие реализации, но в жизни совершенно неприменимые. Так, что в утиль. А лучше отдельной статьёй как делать ненадо. Хотя я сейчас еще гляну, как коверкается код при оптимизации, мож че придумаю и на этот раз |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
ну да, незаметил, кстати а ты this какой передаешь? конструктор TMyLibInterface явно не в курсе о this экземпляра TAnyClass... Добавлено через 2 минуты и 13 секунд собрал под vs2005, пришлось заменить lpCallMethod lpfun = ClassName::CallMethod; на lpCallMethod lpfun = &ClassName::CallMethod; запускаю, валится на асм вставке, и debug и release... |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Lazin, ) не обижайся, но ты жгешь.
У меня в VS - шестерка работает, а вобщем-то забей. Продолжать в этом направлении что-то делать нет смысла, по тому, как я уже упоминал, стандартом является язык а не то как его конкретный компилятор представляет в машинном коде. Еще стандарт, конвенции вызовов функций, но здесь этого не достаточно. |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
ты когда это писал, задумывался о том, что станет с твоим кодом, если пользователь, к примеру объявит хоть одну виртуальную функцию? зы раздел называется "С++ общие вопросы", для асма есть свой раздел |
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Без обид, но жжёшь по-моему тут один ты. Ради экономии нескольких строк придумывать такой неповоротливый костыль... Лучше снабди библиотеку хорошей документацией и примерами, и сделай всё в рамках стандарта. -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| vaddsm |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Если клас будет унаследован от абстрактного или сам станет таковым после объявления виртуальных методов. То в самом начале, экземпляра подобного класса будет описываться VMT. А как это повлияет на алгоритм извлечения this? Конструктор то виртуалить нельзя. Поясни конкретсно, что ты имел ввиду задав этот вопрос, может я действительно не знаю чего-то в этом вопросе. Добавлено через 6 минут и 42 секунды
Темка, то как называлась... "Возможно ли ?". В целях самообразования между прочем. А то, что я предложил -- первый пришедший в голову, вариант. Верняк есть и другие, предложите свои. Добавлено через 12 минут и 56 секунд
Серьезно?? и куда меня послали бы в этом разделе, с вопросом о выполнении кода при инициализации экземпляра объекта c++ класса. В лучшем случае в этот раздел. |
||||||
|
|||||||
| Lazin |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
я подумал что ты пытаешься определять адрес по другому... если его искать в стеке, до должно работать (для одного компилятора), но все равно это костыли...
дело в том, что многие (я например) не знают асм, а то, что ты пишешь не соответствует стандарту С++ и вообще не обязано(мягко говоря) работать |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
В любом случае такое решение получится одноразовым (непереносимым). Я все таки считаю , что лучше смотреть в сторону стандартных языковых возможностей. Вы можете привести пример желаемого взаимодействия клиентского кода с библиотекой без учета реализации? Это сообщение отредактировал(а) mes - 8.9.2008, 13:22 |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Ладно, давайте забудем на время о методе, в адрес которого прозвучала критика. И так, как единогласно было решено – нормального, соответствующего стандартам, способа реализации того, что я хотел видеть – нет.
Предложите свои: Некоторая библиотека предоставляет свой функционал через методы класса TMyLib. Самым простым способом применения, является вызов ее функций в конструкторе, класса для которого она применяется:
Но, так, как библиотека задает поведение методов класса, устанавливает правила. Как если написать virtual или DYNAMIC перед методом, то было бы весьма логично эти правила описывать в том месте, где декларируются эти самые функции. То как я видел это, вы уже видели. |
|||
|
||||
| W4FhLF |
|
||||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Что здесь происходит? Вызов _ИМЯ_МЕТОДА1_, а потом _ИМЯ_МЕТОДА2? Или просто сохранение их адресов? Как тогда потом это применяется?
Что значит задаёт поведение методов класса? Какие правила? Код метода статичен. Следовательно, на его поведение могут влиять только переменные-члены класса или аргументы при вызове. Или в библиотеке существует некоторый унифицированный интерфейс и TMyLib задаёт методы вызова, которые потом где-то кем-то вызываются? Если так, то где и кем? Я пытаюсь въехать в задачу -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Это опять реализация... Пострайтесь именно о интерфейсе/функционале библиотеки рассказать. |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Жуть конечно, но гораздо более переносимо, чем asm вставки Это сообщение отредактировал(а) xvr - 8.9.2008, 18:31 |
|||
|
||||
| vaddsm |
|
||||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
ОГО!
Надо успокоится. Теперь посути, какие недостатки видят участники форума в данном методе?, я лично считаю что код 100% рабочий и переносимый.
Если, честно я немного растерен, а зачем это собственно расказывать здесь, ведь это уже оффтопик.
Статичен, до поры до времени.
Следовательно не так.
Как я вижу, основная задача решена xvr.
Нет, библиотека, патчит методы в рантайме, для решения некоторой удивительной задачи. Но знание об этом вам помогут, дать подсказку мне? Добавлено через 7 минут и 50 секунд xvr, Умница! |
||||||||||
|
|||||||||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Причем, благодаря именно такой реализации мой код будет вызываться значительно раньше всего, что будет описано в конструкторе класса. И это мне тоже, очень надо!
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Ага, поставьте +, будет 100 постов присоеденюсь!
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
ничего не заметили? |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
ага, заметили.. ) никто и не оспаривает реальное его "жутие", однако это не преуменьшает заслуги xvr'a, показавшего пример, который отвечает на вопрос темы. Это сообщение отредактировал(а) mes - 9.9.2008, 09:47 |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
А жутие то в чем собственно? Чес слово, вот на asm - то действительно было жутие. Не тебе стандартов, не тебе переносимости. Мне бы хотелось понять каким критериям не удовлетворяет данный код?
|
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
||||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Good
Продолжите список, пожалуйста. |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
хм, получается что этот макрос на честном слове работает в этом случае? |
|||
|
||||
| vaddsm |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 30.6.2007 Репутация: нет Всего: нет |
Гляньте, как описан в различных компиляторах данный макрос:
В борланде, первый вариант применяется. Решительно не понимаю, как подобная вешь может быть интерпретирована не правильно. Если компилятор всегда знает смещения членов класса (относительно начала класса), как подобный макрос может привести к ошибке? У меня работает верно и при наследовании и для абстрактных классов. Гляньте статью, здесь рассмотрены другие варианты примененя этого макроса, ни слова о несовместимости с ПОД типами. http://www.embedded.com/columns/technicali...equestid=142048 |
|||
|
||||
| Lazin |
|
||||||||||||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
допустим есть пользовательский класс:
и нужно выполнить некоторый код сразу после создания экземпляра этого класса, при этом этот код должен получить доступ к некоторым членам класса, но к какимименно, заранее не известно... для того, что-бы описать член класса, можно использовать такой шаблон:
функция get шаблона получает this и возвращает требуемый член класса, то-же самое можно сделать и для функций:
этот класс - для функций без параметров, но можно сделать и с параметрами... теперь код самого враппера:
первый параметр - пользовательский класс, второй параметр - член пользовательского класса, который нужен будет врапперу, если написать вот так,
то компилятор сгенерирует класс, который ведет себя так-же как и пользовательский, но при создании его экземпляра будет выполнен нужный нам код (в данном случае будет выведено значение члена класса, который передан в качестве параметра), так-же, в отличии от кода с макросами, врапперы можно объединять в цепочки и работать с произвольным набором параметров...
при создании экземпляра класса double_wrap_test будут выведены на экран оба члена класса my_test, далее, можно написать враппер для функций:
который вызывает функцию пользовательского класса, если сделать так:
то после создания объекта my_test, будут выведены параметры a_, потом b_, а потом то, что вернет функция name... так-же можно перехватить момент удаления объекта, и самое приятное в этом, что компилятор теперь сам будет следить за корректностью кода, если я попытаюсь создать объект у которого конструктор принимает больше 4х параметров, код просто не скомпилируется, а не упадет.... когда работает код враппера, все данные пользовательского класса уже гарантировано сконструированы.... Добавлено через 13 минут и 57 секунд
|
||||||||||||||||||||
|
|||||||||||||||||||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
vaddsm, я честно говоря не совсем понимаю что написано в том предложении, оно какое то кривое. Но насколько я понял, там имеется ввиду, что ограничен в рабе с НЕ POD типами.. эта сцитата с C++ references, и я не вижу причин им не доверять. По всей видимости это несовсем\совсем не стандартная фича. Жаль стандарта нет под рукой...
|
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
вот пример опасного кода:
Это сообщение отредактировал(а) mes - 9.9.2008, 15:17 |
||||
|
|||||
| xvr |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Вполне определено - Segmentation Fault |
||||||
|
|||||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
ага.. это требование гораздо более опасно и трудно выполнимей, чем заставлять юзера добавлять строчку в конструктор ) Добавлено через 1 минуту и 59 секунд
ага .. вариант с wrapper определено самый функциональный, переносимый и самое главное безопасный Это сообщение отредактировал(а) mes - 9.9.2008, 15:14 |
||||
|
|||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |