![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Fantasist |
|
|||
|
Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Точно так же. В моем примере функции как раз виртуальные. Адрес берется точно так же, просто указатель несет в себе метку о виртуальности, и при вычислении реального адреса функции (в момент использования) это учитывается. -------------------- Волны гасят ветер... |
|||
|
||||
| RAN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 709 Регистрация: 14.3.2003 Где: Щёлково Моск.обл. Репутация: 5 Всего: 6 |
Нет, этот адрес получается на этапе компиляции. А я имею ввиду следующую ситуацию:
class base { public: virtual void method() {.....} }; class derived:public base { public: virtual void method() {......} }; ......................... base* obj = new derived; .......................... Вопрос: какой адрес функции obj->method() ? Это будет тоже самое, что и &derived::method, хотя obj - указатель на объект класса base. На этапе компиляции этот адрес не известен. А в runtime его, по ходу, не получить. |
|||
|
||||
| Fantasist |
|
|||
|
Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Еще раз. Указатель на член класса не является указателем в прямом смысле слова. Он несет в себе только информацию, достадочную для нахождения адреса члена класса по предоставленному экземпляру объекта, то есть, условно говоря, смещение. Без этого объекта этот "указатель" не имеет никакого смысла. Адрес виртуальной функции так же вычисляется по предоставленному экземпляру объекта. Почитай у Страуструпа - хорошо описанно. -------------------- Волны гасят ветер... |
|||
|
||||
| RAN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 709 Регистрация: 14.3.2003 Где: Щёлково Моск.обл. Репутация: 5 Всего: 6 |
Fantasist, я это всё прекрасно понимаю. Не первый год с ООП.
Страуструпа у меня нет. Искать не хочется, так как проблемы такой передо мной не стоит. Но было бы очень интесно. Может кто знает ответ. Вот и написал. |
|||
|
||||
| Fantasist |
|
||||
|
Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
А в чем тогда вопрос? В чем сомнения? И к чему тогда:
? -------------------- Волны гасят ветер... |
||||
|
|||||
| Jcs |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 156 Регистрация: 1.10.2003 Репутация: нет Всего: нет |
Все работает, как и описал Fantasist, причем и для дочерних классов, а смещене дло функции от начала экземпляра одинаковое и у родителя и у потомка. Есть ли у кого-нить электронный Страустрап?
Буду очень признателен, если кто-нибудь вышлет. [email protected] |
|||
|
||||
| RAN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 709 Регистрация: 14.3.2003 Где: Щёлково Моск.обл. Репутация: 5 Всего: 6 |
Я получаю экземпляр класса. Знаю его базовый класс. Но он может быть экземпляром класса-наследника базового. Вопрос: как узнать адрес некоторой виртуальной функции? Например для выше написанного примера, хочу написать функции, возвращаюшую адрес виртуальной функции:
class base { public: virtual void method() {.....} }; class derived:public base { public: virtual void method() {......} }; ......................... base* obj = new derived; .......................... void* GetMethodAddr(base* x) { ......................Как тут получить адрес x->Method() ? ............................... } |
|||
|
||||
| Jcs |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 156 Регистрация: 1.10.2003 Репутация: нет Всего: нет |
При наследовании новые члены дочернего класса, если таковые имеются, добавляются в конец класса, поэтому все наследуемые функции, в том числе и виртуальные, имеют одно и то же смещение от начала, поэтому достаточно сделать приведение типов и будет работать. Вот рабочий пример (упрощен):
|
|||
|
||||
| RAN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 709 Регистрация: 14.3.2003 Где: Щёлково Моск.обл. Репутация: 5 Всего: 6 |
Не виртуальные функции никуда не добавляются. Они связываются на этапе компиляции. Про смещение можно говорить только, когда имеешь дело с виртуальными функциями. У тебя,Jcs, не совсем верное представление о функционировании наследования. В объекте класса храниться указатель на vtable - виртуальную таблицу. Эта виртуальная таблица одна на все объекты данного класса. А не виртуальные функции туда вовсе не помещаются. И вообще, если это в ответ на мой вопрос, то меня похоже никто не понимает. Жаль. Ну, да ладно. Это так. От любознательности и для общего развития |
|||
|
||||
| Fantasist |
|
|||
|
Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Это точно кто-то кого-то не понимает. -------------------- Волны гасят ветер... |
|||
|
||||
| RAN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 709 Регистрация: 14.3.2003 Где: Щёлково Моск.обл. Репутация: 5 Всего: 6 |
а говоришь не понимаешь. Вот именно это я и хотел услышать. Невозможно, так невозможно. Лезть в vtable конечно можно. Но, во-первых, место vtable в классе не регламентировано (хотя это обычно первое слово), во-вторых, язык,как я понимаю, также не позволяет узнать позицию в vtable адреса виртуальной функции. Короче, спасибо за интересную дискуссию. |
|||
|
||||
| DENNN |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3878 Регистрация: 27.3.2002 Где: Москва Репутация: 1 Всего: 43 |
Я присоединяюсь и предлагаю добавить эту тему в FAQ- вещь вобщем то нужная. |
|||
|
||||
| mr.DUDA |
|
|||
|
3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 25 Всего: 232 |
ЗЫ, а ещё ведь есть виртуальные базовые классы
Вот вам задачка. Если класс порожден вот так:
то как определить, что лежит в vtable класса D ? -------------------- ![]() |
|||
|
||||
| Fantasist |
|
|||
|
Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Что значит как определить? Вестимо, там лежит D::M. Или ты ожидаешь что конструкция: A* a=new D(); a->M(); вызовет A::M()? -------------------- Волны гасят ветер... |
|||
|
||||
| mr.DUDA |
|
|||
|
3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 25 Всего: 232 |
Это я про внутренние потроха vtable, в ответ на:
-------------------- ![]() |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |