![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
knut |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 7.2.2006 Репутация: нет Всего: нет |
добрый день
вот вопрос у меня такой(не совсем извращенный ![]() реально ли такое. функцию-член присвоить указатель на виртуальный метод предка, а потом вызвать её на экземпляре потомка Можно ли ли так вообще делать и если не то почему? ну что то примерно такое
--------------------
|
||||
|
|||||
HappyLife |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 642 Регистрация: 17.5.2006 Репутация: 3 Всего: 8 |
Я не догнал чего ты хочешь.
Тем более не понимаю к чему ты делаешь два класса cBase и что за &cBase::g; вот это вот Г. |
|||
|
||||
Vyacheslav |
|
||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
Я тоже не понял. Особенно
насчет
но могу сказать что
это своершенно разные типы и указатель на метод производного класса тебе не удастся присвоить указателю на метод базового класса. К сожалению :( Добавлено через 7 минут и 9 секунд Дополнительно пример из хелпа по С++Builder, с помощью которого поясняется, зачем разработчики ввели ключевое слово __closure
-------------------- С уважением, Вячеслав Ермолаев |
||||||
|
|||||||
knut |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 7.2.2006 Репутация: нет Всего: нет |
мне надо зделать если возможно такое т.е
указателю на функцию-член присвоить указатель на виртуальный метод предка, а потом вызвать её на экземпляре потомка --------------------
|
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
А можно поподробнее саму задачу описать?
Т.е. в наследнике у нас есть указатель. Ему присваиваем адрес метода базового класса. Потом наследник вызывает этот метод через этот указатель. Вызывается метод базового класса, а так как он виртуальный - то по переданному ему адресу объекта потомка он вызывает необходимую функцию потомка. Правильно я понял? |
|||
|
||||
Vyacheslav |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
И никак иначе? Тяжело с Вами.
Я понимаю, что торг не уместен, но может это спасет отца русской демократии ![]()
-------------------- С уважением, Вячеслав Ермолаев |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Мне кажется, это зависит от компилятора. Если он присваивает указателю адрес конкретной функции (предка), то фиг вам. А если адрес специального стабика, где выполняется переадресация, то запросто. Не в курсе, что написано в стандарте. Знаю только, что MSVC это делает. Т.е. указатель, которому присвоен "адрес" виртуальной функции предка, при подстановке this потомка вызовет правильную функцию. А вот старый борланд (еще досовских времен) - нет. Что борланд делает сейчас - не знаю. -------------------- ... |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Блин, а я думал, что если метод класса обычный - то адрес его определяется линковкой, а если виртуальный - то во время исполнения, при помощи таблицы виртуальных методов... Соответственно, если указатель будет указывать на виртуальный метод базового класса, но в момент вызова ему будет передан адрес объекта-потомка, то все должно нормально сработать - по адресу объекта будет определен тип, найдена функция для этого типа и вызвана... |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Сам подумай, что такое адрес функции-члена? Это просто адрес. Откуда при вызове по этому адресу возьмется информация о полиморфизме?
Когда компилятор видит в коде вызов виртуальной функции, он не подставлет ее адрес непосредственно, а делает промежуточную переадресацию: из объекта выковыривается адрес vtable, из vtable по номеру берем адрес реально-вызываемой функции. Вот тебе и полиморфизм. А если мы присваиваем указателю адрес, то адрес чего? MSVC выкручивается просто: и в первом и во втором случае (т.е. и при вызове виртуальной функции, и при использовании ее адреса) генерит небольшой стаб, где выполняет вышеописанную переадресацию. А в качестве адреса выдает адрес этого самого стаба. В результате получается, что как бы ты не использовал виртуальную функцию, реально ты получаешь адрес стаба. Именно поэтому все всегда виртуально работает. -------------------- ... |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Earnest, Да, конечно, я ступил. Я подумал об адресе объекта, а не об адресе метода.
Бывает... Век живи - век учись. И все равно дураком помрешь... |
|||
|
||||
knut |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 7.2.2006 Репутация: нет Всего: нет |
Vyacheslav,
Так работает ![]()
--------------------
|
||||||||
|
|||||||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |