| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Вопрос по указательям на функции |
| Автор: knut 20.4.2007, 15:21 | ||
| добрый день вот вопрос у меня такой(не совсем извращенный реально ли такое. функцию-член присвоить указатель на виртуальный метод предка, а потом вызвать её на экземпляре потомка Можно ли ли так вообще делать и если не то почему? ну что то примерно такое
|
| Автор: HappyLife 20.4.2007, 15:47 |
| Я не догнал чего ты хочешь. Тем более не понимаю к чему ты делаешь два класса cBase и что за &cBase::g; вот это вот Г. |
| Автор: Vyacheslav 20.4.2007, 16:01 | ||||||
| Я тоже не понял. Особенно насчет
но могу сказать что
это своершенно разные типы и указатель на метод производного класса тебе не удастся присвоить указателю на метод базового класса. К сожалению :( Добавлено через 7 минут и 9 секунд Дополнительно пример из хелпа по С++Builder, с помощью которого поясняется, зачем разработчики ввели ключевое слово __closure
|
| Автор: knut 20.4.2007, 16:14 |
| мне надо зделать если возможно такое т.е указателю на функцию-член присвоить указатель на виртуальный метод предка, а потом вызвать её на экземпляре потомка |
| Автор: Anikmar 20.4.2007, 17:16 |
| А можно поподробнее саму задачу описать? Т.е. в наследнике у нас есть указатель. Ему присваиваем адрес метода базового класса. Потом наследник вызывает этот метод через этот указатель. Вызывается метод базового класса, а так как он виртуальный - то по переданному ему адресу объекта потомка он вызывает необходимую функцию потомка. Правильно я понял? |
| Автор: Vyacheslav 20.4.2007, 17:18 | ||
| И никак иначе? Тяжело с Вами. Я понимаю, что торг не уместен, но может это спасет отца русской демократии
|
| Автор: Anikmar 20.4.2007, 21:07 | ||
Блин, а я думал, что если метод класса обычный - то адрес его определяется линковкой, а если виртуальный - то во время исполнения, при помощи таблицы виртуальных методов... Соответственно, если указатель будет указывать на виртуальный метод базового класса, но в момент вызова ему будет передан адрес объекта-потомка, то все должно нормально сработать - по адресу объекта будет определен тип, найдена функция для этого типа и вызвана... |
| Автор: Earnest 20.4.2007, 21:20 |
| Сам подумай, что такое адрес функции-члена? Это просто адрес. Откуда при вызове по этому адресу возьмется информация о полиморфизме? Когда компилятор видит в коде вызов виртуальной функции, он не подставлет ее адрес непосредственно, а делает промежуточную переадресацию: из объекта выковыривается адрес vtable, из vtable по номеру берем адрес реально-вызываемой функции. Вот тебе и полиморфизм. А если мы присваиваем указателю адрес, то адрес чего? MSVC выкручивается просто: и в первом и во втором случае (т.е. и при вызове виртуальной функции, и при использовании ее адреса) генерит небольшой стаб, где выполняет вышеописанную переадресацию. А в качестве адреса выдает адрес этого самого стаба. В результате получается, что как бы ты не использовал виртуальную функцию, реально ты получаешь адрес стаба. Именно поэтому все всегда виртуально работает. |
| Автор: Anikmar 20.4.2007, 21:35 |
| Earnest, Да, конечно, я ступил. Я подумал об адресе объекта, а не об адресе метода. Бывает... Век живи - век учись. И все равно дураком помрешь... |
| Автор: knut 21.4.2007, 14:52 | ||||||
Vyacheslav,
Так работает
|