Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.07.2012, 21:38   #11
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Уф
class CParent;
class CChild : public CParent;
CParent* ptr = new CChild;
CChild* crash = dynamic_cast<CChild*>(ptr);
typeid(ptr) == ?
Пример не корректный. Нельзя наследоваться от неполных типов.

А что касается динамик_каста: его нельзя использовать для не_полиморфных типов. Что замечательно вычисляется времени компиляции:


Код:
struct Base{};
struct Derive1: Base {};
void Foo(Base* ptr){ cout<< typeid(*ptr).name()<<endl; }

int main()
{
    Base* _ptr = new Derive1();
    
    //: error C2683: dynamic_cast: "Base" не является полиморфным типом
    //Derive1* ptr1 = dynamic_cast<Derive1*>(_ptr);
   
    Foo(_ptr); //вывод: struct Base
    
    return 0;
}

Добавь в базу хоть один виртуальный метод, и тут же заработает RTTI

Последний раз редактировалось _Bers; 23.07.2012 в 21:43.
_Bers вне форума Ответить с цитированием
Старый 23.07.2012, 21:49   #12
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

Ну что же, соглашусь. Признаюсь, RTTI избегаю как огня и соответно не знаю тонкостей.
waleri вне форума Ответить с цитированием
Старый 23.07.2012, 22:04   #13
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Ну что же, соглашусь. Признаюсь, RTTI избегаю как огня и соответно не знаю тонкостей.
Ну я тоже избегаю. Считаю его присутствие в своем коде "исключительно костыльным решением, продиктованным несовершенством мира".

Хотя я не вижу ничего плохого в статик_тайп_ид. Оно же уже не кушает время в рантайме.

А фокус тут следующий: Предположим, есть полиморфная иерархия.
У потомка создаётся уникальный айдишник (привязка к параметру шаблона, ну или тупо к какому нибудь енуму).

В интерфейсе базы есть метод
Код:
virtual const type_info& GetTypeInfo()=0;
А потомок создает тупо тайпдеф:

Код:
//где то в объявлении класса
typedef RTTI<T> RTTI_t;
ну или оно же, ток от енума.

И реализует интерфейсный метод:

Код:
virtual const type_info& GetTypeInfo()const { return typedeid(RTTI_t); }
Таким образом, полиморфный потомок возвращает свой как бы ид, который вычисляется на этапе компиляции, потому что сам по себе инстанс RTTI<T> не содержит виртуальных методов.

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

Получаем идентификацию для полиморфов, без издержек в рантайме.

А вообще, есть целые паттерны, как изготовить быстрый RTTI для полиморфов, с "автоматическим уникальным ид", и тп.
_Bers вне форума Ответить с цитированием
Старый 23.07.2012, 23:38   #14
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

То, что вы делаете это то же RTTI, только с вашими структурами - в принципе никакой разницы.
RTTI вкллючает скрытый виртуальный метод, который возрващает структуру, в которой тоже нет виртуальных методов. Ключевое то, что в объекте нужно делать виртуальный метод, а не то, как сгенерить уникальное ID для каждого типа. Тут даже и template ненужен static type_info сойдет не хуже.

Время в рантайме кушает не определение типа (там то же самое что и у вас) а динамический каст - это может оказаться довольно медленным, особено если есть множественное или виртуальное наследование.
waleri вне форума Ответить с цитированием
Старый 23.07.2012, 23:52   #15
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
То, что вы делаете это то же RTTI, только с вашими структурами - в принципе никакой разницы.
RTTI вкллючает скрытый виртуальный метод, который возрващает структуру, в которой тоже нет виртуальных методов. Ключевое то, что в объекте нужно делать виртуальный метод, а не то, как сгенерить уникальное ID для каждого типа. Тут даже и template ненужен static type_info сойдет не хуже.

Время в рантайме кушает не определение типа (там то же самое что и у вас) а динамический каст - это может оказаться довольно медленным, особено если есть множественное или виртуальное наследование.
Опять двадцать пять: унаследовался от полиморфа? typeid задействуют RTTI.

А если сделать typeid(ptr->GetTypeInfo() )

Где GetTypeInfo возвращает const type_info& не_полиморфного типа, а значит, вычисляемого времени компиляции, то никаких потерь в рантайме уже не будет. Не будет никаких динамических кастов.

Смысл в том, что бы для полиморфа не использовать встроенное RTTI
_Bers вне форума Ответить с цитированием
Старый 24.07.2012, 09:16   #16
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

Цитата:
Сообщение от _Bers Посмотреть сообщение
Где GetTypeInfo возвращает const type_info& не_полиморфного типа, а значит, вычисляемого времени компиляции, то никаких потерь в рантайме уже не будет.
Стандартный RTTI тоже возвращает структуру неполиморфного типа, вычисляемой во время компиляции - так где отличия? А если нет разницы, тогда зачем это делать? Таким образом вы будете вызывать виртуальную функцию сами, вот и все, тогда как в случае RTTI о подробностях будет заботиться компилятор. Кроме того, вы же сами говорили, что если у класса нет виртуальной таблицы typeid будет работать невиртуально а type_info все равно не полиморфна.

Единственный смысл делать свое RTTI это ограничить функционал и соотвественно размер программы но смысла в этом нет. Чтоб сделать хоть чтото смысленное надо будет заставлять программиста не ошибаться, ведь в type_info надо будет ставить ссылку на родителя (и не дай бог родителей) а без динамического каста вообще все теряет смысл, кроме одного частного случая когда у всех классов один и только один родитель, чего за пределами академических задач редко увидиш.
waleri вне форума Ответить с цитированием
Старый 24.07.2012, 12:16   #17
rmv240899
Форумчанин
 
Регистрация: 18.02.2012
Сообщений: 155
По умолчанию

ТС, так не передавайте в функцию void *, сделайте её шаблонной. Например так.

Последний раз редактировалось rmv240899; 24.07.2012 в 12:19.
rmv240899 вне форума Ответить с цитированием
Старый 24.07.2012, 14:12   #18
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,331
По умолчанию

А не проще будет сделать несколько функций с одним именем и с разным типом аргументов для разных структур?
waleri вне форума Ответить с цитированием
Старый 24.07.2012, 16:00   #19
rmv240899
Форумчанин
 
Регистрация: 18.02.2012
Сообщений: 155
По умолчанию

ТС уже говорил, что вариант с перегрузкой ему не подходит.
rmv240899 вне форума Ответить с цитированием
Старый 24.07.2012, 20:54   #20
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Стандартный RTTI тоже возвращает структуру неполиморфного типа, вычисляемой во время компиляции - так где отличия?
Смысл не в том, что именно возвращает typeid, а в том, что ты скармливаешь ей.

typeid(ptr->GetTypeInfo() );

Что именно ты пихаешь в качестве аргумента typeid?
Если ты пихаешь туда полиморфный объект, то прими мои поздравления: динамик_каст и потери производительности - твои лучшие друзья.
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Написание программ (древовидные структуры, структуры неспециального вида и т.д.) Green Gin Фриланс 2 27.04.2012 15:26
Управляющие структуры. Программирование алгоритмов разветвляющейся структуры. Лёнка Компоненты Delphi 1 23.04.2012 15:03
C# определение ф-и Lucky777 Помощь студентам 4 10.06.2011 01:00
Определение по IP ProgDel Работа с сетью в Delphi 3 08.11.2010 22:14
Линейные структуры - что это? (определение) MR_Andrew Помощь студентам 6 07.10.2009 18:38