Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как получить тип через указатель на базовый класс? 
V
    Опции темы
Alek86
Дата 20.12.2007, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



то есть, если я правильно понял, ты хочешь вызывать функции не виртуально (через таблицу виртуальных функций) а напрямую?
вообще избавиться от виртуальности функций?


--------------------
user posted image    user posted image
PM MAIL   Вверх
MAKCim
Дата 20.12.2007, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



georain, 
а если так сделать
Код

class A {
private:
    void __a1() { ... }
    void __a2() { ... }
...
    void __an() { ... }
public:
    virtual void a1() { __a1(); }
    virtual void a2() { __a2(); }
...
    virtual void an() { __an(); }
    virtual void combination(int flags) {
         // тут вызывать __a1(), __a2(), ... напрямую
    }
};



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Alek86
Дата 20.12.2007, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



исправьте меня, если ошибусь, но, вроде, единственные издержки в вызове виртуальных функций - это то, что они вызываются через указатели, и ускорить их вызов можно, лишь сделав их невиртуальными...

Добавлено через 29 секунд
Цитата(MAKCim @  20.12.2007,  14:04 Найти цитируемый пост)
а если так сделать


Цитата(georain @  20.12.2007,  13:52 Найти цитируемый пост)
Конечно есть вариант в самих классах определять дополнительные виртуальные функции с необходимой последовательностью, но их там и так много, перебор получается, к тому-же это сильно увеличит размер виртуальных таблиц.




--------------------
user posted image    user posted image
PM MAIL   Вверх
MAKCim
Дата 20.12.2007, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Alek86, 
Код

class A;

typedef void (*callback_t)(A * const);

class A {
private:
    void __a1() { ... }
    void __a2() { ... }
...
    void __an() { ... }

    static callback_t __array[NR_COMBINATION];

    static void combination1(A * const ptr) {
        // последовательность вызовов 1
    }

    static void combination2(A * const ptr) {
        // последовательность вызовов 2
    }
...
    static void combinationn(A * const ptr) {
        // последовательность вызовов NR_COMBINATION
    }
public:
    virtual void a1() { __a1(); }
    virtual void a2() { __a2(); }
...
    virtual void an() { __an(); }
    virtual void combination(int number) {
         __array[number](this);
    }
};

callback_t A :: __array[NR_COMBINATION] = {
    &A :: combination1,
    &A :: combination2,
...
    &A :: combinationn 
};



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Alek86
Дата 20.12.2007, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



тогда по вопросу осталась мелочь - побыстрее определить, что текущий указатель указывает именно на A, а не на B и вызвать определенную статическую функцию с кастанутым текущим указателем...

может, typeof поможет

Это сообщение отредактировал(а) Alek86 - 20.12.2007, 14:37


--------------------
user posted image    user posted image
PM MAIL   Вверх
HappyLife
Дата 20.12.2007, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 642
Регистрация: 17.5.2006

Репутация: 3
Всего: 8



Кхм.... интересно а насколько дорого стоит вызов виртуальной функции?
PM MAIL   Вверх
Lazin
Дата 20.12.2007, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Не знаю насколько я попал в тему...
избавиться от дополнительных виртуальных ф-й и вызывать правильные не виртуальные методы в производных классах позволяет шаблон проектирования Curiously recurring template
PM MAIL Skype GTalk   Вверх
MAKCim
Дата 20.12.2007, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(HappyLife @  20.12.2007,  14:37 Найти цитируемый пост)
Кхм.... интересно а насколько дорого стоит вызов виртуальной функции? 

Код

    mov    eax, dword [edx]
    push    edx
    call    dword [eax + OFFSET]

вместо
Код

    push    edx
    call    <displacement>



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Alek86
Дата 20.12.2007, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



ну, и еще ее нельзя инлайнить, в общем случае


--------------------
user posted image    user posted image
PM MAIL   Вверх
Earnest
Дата 25.12.2007, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(Lazin @  20.12.2007,  15:37 Найти цитируемый пост)
избавиться от дополнительных виртуальных ф-й и вызывать правильные не виртуальные методы в производных классах позволяет шаблон проектирования Curiously recurring template 

Строго говоря, вовсе необязательно CRT - любой шаблон обеспечивает статический полиморфизм. Только не всегда можно заменить динамический полиморфизм статическим - для этого нужно знать типы на этапе компиляции.

Автору: большое дерево классов + много виртуальных функций - уже надо что-то в консерватории поправить. Если достаточно определить в одном месте тип, а потом можно вызвать конкретную функцию, так и сделай именно эту функцию виртуальной (а остальные - невиртуальными). Замена на callback, как вроде кто-то предлагал - хрень редьки не слаще, тот же косвенный вызов с теми же издержками. 

Кстати, они действительно небольшие. Ты уверен, что стОит париться, т.е. узкое место с производительностью именно здесь? Профилятор это показал? Или ты просто так думаешь, заранее?



--------------------
...
PM   Вверх
baldina
Дата 25.12.2007, 18:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата

Строго говоря, вовсе необязательно CRT - любой шаблон обеспечивает статический полиморфизм. Только не всегда можно заменить динамический полиморфизм статическим - для этого нужно знать типы на этапе компиляции.

smile

но CRT там не поможет. если идет борьба за пару инструкций, это не выход - косвенный вызов остается.


Это сообщение отредактировал(а) baldina - 25.12.2007, 18:19
PM MAIL   Вверх
georain
Дата 25.12.2007, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



В общем я сделал все виртуальные функции обычными, и запихал все свои комбинации в новые виртуальные функции, в итоге добился того что и хотел: вызов только одно виртуальной функции для комбинации. В итоге выиграл 4% производительности. Я считаю что это прилично, и труд был потрачен не зря.

На счет моего вопроса: для решения таких проблем нужно очень хорошо представлять, что уже известно на этапе компиляции, а что нет. Задавая вопрос "Как я могу (и могу ли вообще) получить указатель на класс, на который указывает указатель на базовый класс?", я допустил логическую ошибку. MAKCim уже сказал, что не могу, потому что (как сказал Earnest) узнать на какой класс указывает базовый указатель мы может только на этапе выполнения, а связывание по типу происходит на этапе компиляции (например вызов нужной функции, в зависимости от типа указателя).

Спасибо всем за огромную помощь, как говорится, дурная голова никому покоя не дает.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0647 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.