Как узнать тип объекта c
Перейти к содержимому

Как узнать тип объекта c

  • автор:

Узнать реальный тип объекта

Предположим, есть тип базовый класс SceneObject и есть производные от него классы. Я хочу хранить массив объектов этого класса, для этого завожу vector < SceneObject*>obj. Добавляю туда некоторые объекты производных классов. А когда достаю их оттуда, я хочу узнать их реальный тип. typeid(obj[i]).name() всегда выдает тип SceneObject*. Как узнать реальный тип объекта?( Или может быть, я все делаю неправильно. Как тогда сделать массив объектов, производных от одного класса, чтобы потом можно было определить какой это объект?

Отслеживать
задан 15 мая 2016 в 9:56
195 1 1 серебряный знак 9 9 бронзовых знаков

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

Информация о типе — это дополнительная информация. Когда у вас есть виртуальные функции — есть и их таблица, которая по сути и есть информацией о конкретном типе.

Без этого надо хранить информацию о типе где-то отдельно.

Но как вы хотите использовать эту информацию? Для чего? Обычно — без виртуальных функций — она попросту бессмысленна.

Кстати, раз уж вы пользуетесь указателями и иерархией классов — то учтите, что с точки зрения безопасности деструктор базового класса должен быть объявлен как виртуальный!

Отслеживать
ответ дан 15 мая 2016 в 10:13
218k 15 15 золотых знаков 117 117 серебряных знаков 229 229 бронзовых знаков

Для определения реального типа объекта вы можете воспользоваться dynamic_cast : TYPE* dynamic_cast (object);

Отслеживать
ответ дан 15 мая 2016 в 10:00
Мстислав Павлов Мстислав Павлов
6,757 2 2 золотых знака 18 18 серебряных знаков 40 40 бронзовых знаков

Для классов, не содержащих виртуальные функции, это не работает( Может быть, можно как-то по-другому?

15 мая 2016 в 10:07
а тут разве не нужно знать к чему кастовать? а вопросе вроде обратный вопрос?
15 мая 2016 в 10:08

Да, тут нужно знать( Но можно сделать иерархию if-else и попробовать поприводить ко всему, при некотором желании(хотя это медленно и неоптимально)

15 мая 2016 в 10:11

Очевидно, что Вы неправильно выводите имя, должно быть так: typeid(*obj[i]).name() , но это будет работать лишь в том случае, когда SceneObject является полиморфным, т.е. содержит хотя бы одну виртуальную функцию. Это требуется потому, что без этого RTTI по классу отсутствует, и оператору typeid просто неоткуда узнать, что же за тип ему реально передан.

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

Что касается правильно/не правильно. Обычно, если появляется задача узнать реальный тип данных, то это на 99% ошибка дизайна. Реальный тип практически никогда знать не нужно, для выполнения конкретной реализации существует полиморфное поведение, то есть виртуальные функции.

Как узнать тип объекта c

Допустим есть объект a, какого то типа. Вот этот тип нам и нужно определить, например для создания другого объекта такого же типа. Это звучит конечно немного глупо, так как мы всегда знаем какого типа объект, ну а все таки, например в таком контесте:

. // тут очень много кода, например чужого. . // и у нас есть объект x. // А тут нам нужно создать копию объекта x. tpye(x) a(x); // Например, type это такой волшебный преобразователь. . 

Есть способ вот такой:

templateclass T> void Create(T &x)

Но этот тип T никак не могу вынести за пределы этой функции.

Может я чего то не знаю в современном C++?

Re: как определить тип объекта?

От: LaFlour blog: http://spaces.live.com/laflour
Дата: 26.12.02 06:58
Оценка:

Здравствуйте, comer, Вы писали:

C>Допустим есть объект a, какого то типа. Вот этот тип нам и нужно определить, например для создания другого объекта такого же типа. Это звучит конечно немного глупо, так как мы всегда знаем какого типа объект, ну а все таки, например в таком контесте:

Не пробывал задавать новый тип по полученному
но typeid позволяет определить тип

C>

 int i; cout typeid(i).name; //вывыдет int C>

или может я чтото непонял?

:: Into my SONY MDR-R10 sound «DJ Groove — Ноктюрн» ::
Re: как определить тип объекта?

От: Dima2
Дата: 26.12.02 07:41
Оценка: 8 (1)

Вот смотри здесь немного

Автор: DarkGray
Дата: 12.04.02
Автор: DarkGray
Дата: 14.04.02
Re: как определить тип объекта?

От: jazzer Skype: enerjazzer
Дата: 26.12.02 08:07
Оценка: 4 (1)

Здравствуйте, comer, Вы писали:

C>Допустим есть объект a, какого то типа. Вот этот тип нам и нужно определить, например для создания другого объекта такого же типа. Это звучит конечно немного глупо, так как мы всегда знаем какого типа объект, ну а все таки, например в таком контесте:

C>

C>. // тут очень много кода, например чужого. C>. // и у нас есть объект x. C> // А тут нам нужно создать копию объекта x. C>tpye(x) a(x); // Например, type это такой волшебный преобразователь. C>. C>

см. ниже.

C>Есть способ вот такой:

C>

C>templateclass T> void Create(T &x) < T a(x); >C>

C>Но этот тип T никак не могу вынести за пределы этой функции.

Это невозможно, ибо вызов функции — это выражение, а оно по грамматике не может стоять на месте типа в объявлении.

C>Может я чего то не знаю в современном C++? .

Такого способа, к сожалению, нет, но, возможно, он появится, по крайней мере, Строуструп за это ратует (и я лично это очень поддерживаю), можете посмотреть на ео страничке.

jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got If you always do what you always did

Re: как определить тип объекта?

От: orangy http://twitter.com/orangy
Дата: 26.12.02 11:48
Оценка:

Здравствуйте, comer, Вы писали:

C>Допустим есть объект a, какого то типа. Вот этот тип нам и нужно определить, например для создания другого объекта такого же типа.
Лучше используй парадигму создание-по-прототипу.

class IPrototype < public: virtual IPrototype *Create() = 0; >; class A : public IPrototype < public: A(int b) < . >virtual IPrototype *Create() < return new A(10); > >;

«Develop with pleasure!»
Re[2]: как определить тип объекта?

От: comer http://getboost.codeplex.com/
Дата: 26.12.02 12:15
Оценка:

Здравствуйте, Dima2, Вы писали:

D>http://www.rsdn.ru/Forum/Message.aspx?mid=44873
Автор: DarkGray
Дата: 12.04.02

Да, спасибо, вот здесь как раз и нашел ответ Павла Кузнецова, что в GCC есть __typeof. Мне как раз для GCC. Пока подобной вещи нет в стандарте. Сегодня попробую.

Re[2]: как определить тип объекта?

От: comer http://getboost.codeplex.com/
Дата: 26.12.02 12:18
Оценка:

Здравствуйте, jazzer, Вы писали:

J>Такого способа, к сожалению, нет, но, возможно, он появится, по крайней мере, Строуструп за это ратует (и я лично
это очень поддерживаю), можете посмотреть на ео страничке.

Я тоже двумя руками за! На этапе компиляции всегда должны быть способы узнать об объекте, типе, функции, все то, что знает о нем компилятор, или почти все . А то не честно как то, компилятор знает, а пользователю — болт. Извините за эмоции.

Re: как определить тип объекта?

От: Кодт
Дата: 26.12.02 13:10
Оценка:

Здравствуйте, comer, Вы писали:

C>Может я чего то не знаю в современном C++?

Посмотри в сторону Александреску и его библиотеки Loki, и его же книги (www.moderncppdesign.com)
Может, чего полезного подчерпнешь

Перекуём баги на фичи!
Re[2]: как определить тип объекта?

От: comer http://getboost.codeplex.com/
Дата: 26.12.02 13:50
Оценка:

Здравствуйте, Кодт, Вы писали:

К>Посмотри в сторону Александреску и его библиотеки Loki, и его же книги (www.moderncppdesign.com)
К>Может, чего полезного подчерпнешь

Там эмуляция typeof вряд ли есть

Re[3]: как определить тип объекта?

От: Кодт
Дата: 26.12.02 14:07
Оценка:

Здравствуйте, comer, Вы писали:

C>Там эмуляция typeof вряд ли есть
То есть

Но, с другой стороны, — а откуда возникла такая задача?
Может, ее по-другому можно решить? Раскрой тайну.

Александреску как раз показывает, что ловкость рук творит чудеса.

Перекуём баги на фичи!
Re[4]: как определить тип объекта?

От: comer http://getboost.codeplex.com/
Дата: 26.12.02 15:55
Оценка:

Здравствуйте, Кодт, Вы писали:

C>>Там эмуляция typeof вряд ли есть
К>То есть
Без обид, я ведь искал typeof. IMHO, решения нет. Просто в данном случае loki вряд ли поможет.

К>Но, с другой стороны, — а откуда возникла такая задача?
К>Может, ее по-другому можно решить? Раскрой тайну.
Всегда можно решить по другому, я и решаю именно так.
Понятное дело, что тип мы знаем, что где то выше этот объект описан.
Но ты иногда изменял у какого нибудь объекта a тип vector, например на list, или еще на что нибудь подобное?
А потом бегать по все программе, и заменять vector::iterator на list::iterator.

Конечно, можно было бы определить typedef для данного конкретного объекта a, или все алгоритмы работающие с a описывать в виде шаблонных функция. Но если бы был typeof(), можно было бы решать элегантнее.

Так же как и вообще без шаблонов когда то писали, и ничего, пользовались макросами, и т.п.

8.6. Определение типа объекта во время выполнения

Во время выполнения требуется динамически узнавать тип определенного класса.

Для запроса, на объект какого типа указывает адрес объекта, используйте идентификацию типов во время выполнения (обычно называемую просто RTTI — runtime type identification). Пример 8.6 показывает, как это делается.

Пример 8.6. Использование идентификации типов во время выполнения

using namespace std;

class Derived : public Base <>;

// Используем typeid для проверки равенства типов

if (typeid(b) == typeid(d)) < // No

if (typeid(b) == typeid(bb)) < // Yes

it (typeid(a) == typeid(Derived)) < // Yes

Пример 8.6 показывает, как использовать оператор typeid для определения и сравнения типов объектов, typeid принимает выражение или тип и возвращает ссылку на объект типа type_info или его подкласс (что зависит от реализации). Возвращенное значение можно использовать для проверки на равенство или получить строковое представление имени типа. Например, сравнить типы двух объектов можно так.

if (typeid(b) == typeid(d))

Это выражение возвращает истину, если возвращаемые объекты type_info равны. Это работает благодаря тому, что typeid возвращает ссылку на статический объект, так что при его вызове для двух объектов одного и того же типа будут получены две ссылки на один и тот же объект и сравнение вернет истину.

typeid также можно использовать непосредственно с типом, как здесь.

if (typeid(d) == typeid(Derived))

Это позволяет явно проверять определенный тип.

Вероятно, наиболее часто typeid используется для отладки. Для записи имени типа используйте type_info::name, как здесь.

При передаче объектов различных типов это может быть очень полезно. Строка, завершающаяся нулем, возвращаемая name, зависит от реализации, но вы можете ожидать (но не полагаться на это), что она будет равна имени типа. Это также работает и для встроенных типов.

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

Если obj имеет тип X, сделать что-то одно, а если obj имеет тип Y, сделать что-то другое.

Это плохой дизайн, потому что клиентский код теперь содержит избыточные зависимости от типов используемых объектов. Это также приводит к большой каше из if/then кода, который то и дело повторяется, если для объектов типов X или Y требуется различное поведение. Объектно-ориентированное программирование и полиморфизм существуют в большой степени для того, чтобы избавить нас от написания подобного рода логики. Если для какого-либо семейства связанных классов требуется зависящее от типа поведение, то они все должны наследоваться от какого-то базового класса и использовать виртуальные функции, динамически вызывая различное поведение в зависимости от типа.

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

Читайте также

Глава 27 Динамическая загрузка во время выполнения

Глава 27 Динамическая загрузка во время выполнения Загрузка разделяемых (совместно используемых) объектов во время выполнения может оказаться полезным способом для структурирования собственных приложений. Если правильно организовать этот процесс, то тогда можно будет

Практическое определение объекта

Практическое определение объекта Вы можете заметить, что порой представить объект VBA в материально осязаемом виде не так-то просто. Но это и к лучшему — чем дальше вы уходите от материализации объектов, тем свободнее будете себя чувствовать при работе со всем диапазоном

Определение объекта Range

Определение объекта Range В Excel имеется несколько возможных методов идентификации диапазона из одной или нескольких ячеек, на который должен воздействовать написанный код. Для достижения данной цели используются следующие.Стандартная ссылка на ячейку. Так называемый

15.8.2. Emacs и отладка во время выполнения

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

15.8.2. Emacs и отладка во время выполнения

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

1.4.1. Кодирование во время выполнения

1.4.1. Кодирование во время выполнения Мы уже упоминали директивы load и require. Важно понимать, что это не встроенные предложения и не управляющие конструкции; на самом деле это методы. Поэтому их можно вызывать, передавая переменные или выражения как параметры, в том числе

Определение «объекта приложения»

Определение «объекта приложения» В настоящее время тип HelloClass решает две задачи. Во-первых, этот класс определяет точку входа в приложение (метод Main()). Во-вторых, HelloClass поддерживает элемент данных и несколько конструкторов. Все это хорошо и синтаксически правильно, но

6.12.1. Определение объекта map и заполнение его элементами

6.12.1. Определение объекта map и заполнение его элементами Чтобы определить объект класса map, мы должны указать, как минимум, типы ключа и значения. Например:mapstring,int word_count;Здесь задается объект word_count типа map, для которого ключом служит объект типа string, а ассоциированным с ним

19.1. Идентификация типов во время выполнения

19.1. Идентификация типов во время выполнения * RTTI позволяет программам, которые манипулируют объектами через указатели или ссылки на базовые классы, получить истинный производный тип адресуемого объекта. Для поддержки RTTI в языке C++ есть два оператора: оператор dynamic_cast

Выяснение типа объекта в период выполнения

Выяснение типа объекта в период выполнения Разработчики ОО-ПО вскоре вырабатывают здоровую неприязнь к любому стилю вычислений, основанному на явном выборе между различными типами объекта. Полиморфизм и динамическое связывание намного предпочтительнее. Однако в

Как узнать тип переменной C#

using System ; public class MyBaseClass < >public class MyDerivedClass : MyBaseClass < >public class Test < public static void Main () < MyBaseClass myBase = new MyBaseClass (); MyDerivedClass myDerived = new MyDerivedClass (); object o = myDerived ; MyBaseClass b = myDerived ; Console . WriteLine ( "mybase: Type is " , myBase . GetType ()); Console . WriteLine ( "myDerived: Type is " , myDerived . GetType ()); Console . WriteLine ( "object o = myDerived: Type is " , o . GetType ()); Console . WriteLine ( "MyBaseClass b = myDerived: Type is " , b . GetType ()); > > // The example displays the following output: // mybase: Type is MyBaseClass // myDerived: Type is MyDerivedClass // object o = myDerived: Type is MyDerivedClass // MyBaseClass b = myDerived: Type is MyDerivedClass

int n1 = 12; int n2 = 82; long n3 = 12; Console . WriteLine («n1 and n2 are the same type: «, Object .ReferenceEquals(n1. GetType (), n2. GetType ())); Console . WriteLine («n1 and n3 are the same type: «, Object .ReferenceEquals(n1. GetType (), n3. GetType ())); // The example displays the following output: // n1 and n2 are the same type: True // n1 and n3 are the same type: False

n1 and n2 are the same type: True n1 and n3 are the same type: False

В других языках

  • Си: такой функции нет.
  • C++: похожую задачу решает функция typeid()

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *