YznIT Ответов: 3

Поиск типа объекта в C++?


Hej и :)

Как я могу определить тип класса конкретного объекта в c++ или как лучше всего узнать, какой тип объекта находится в моем массиве ?
Например, что делать, если я хочу установить новый возраст только для всех кошек, не зная, есть ли позиции(индекс) в массиве.

И, пожалуйста, напишите if-заявление или что-то еще, чтобы я мог лучше его понять.

Спасибо!

Что я уже пробовал:

//Базовый класс
класс животных
{
частный:
std:: имя строки;
инт возраста ;

общественный:
Animal (std:: string name = "Unknown", int age =0);
~Животное();
};

//производный класс
класс собака: общественное животное
{
общественный:
Dog (std:: string name = "Unknown", int age =0);
~Собака();
void setAge (int newAge) const;
};

//производный класс
класс кошка: общественное животное
{
общественный:
Cat(std:: string name = "Unknown", int age =0);
~Кошка();
void setAge (int newAge) const;
};


//в main.cpp

Животное *arr[5];

arr[i] = новый кот ("cat1", 11);
arr[i] = новая собака ("dog1", 12);
arr[i] = новая собака ("dog2", 13);
arr[i] = новая собака ("dog3", 14);
arr[i] = новый кот ("cat2", 15);

3 Ответов

Рейтинг:
25

CPallini

Взгляните также на оператор typeid[^].


Richard MacCutchan

+5-легко, когда знаешь как.

Рейтинг:
19

nv3

У вас есть несколько альтернатив:

(а) добавление собственного поля типа в базовый класс

class Animal
{
public:
   int m_type;

   ...
}

Это не очень объектно-ориентировано и было бы моим последним средством.

(B) используют информацию системы типов с++:
Cat* pCat = dynamic_cast<Cat*> (arr[i]);
if (pCat != NULL)
   pCat->age = 14;

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

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

(c) создайте виртуальную функцию, которая делает все, что вы хотите. Например, предположим, что вы хотите настроить возраст всех животных по какой-то формуле, которая является специфичной для типа животного. Вы можете реализовать виртуальную функцию, например:
class Animal
{
public:
   virtual void AdjustAge () = 0;

...
}

class Cat
{
public:
   virtual void AdjustAge ()
   {
      age = age * CAT_SPECIFIC_FACTOR;
   }
...
}

class Dog
{
public:
   virtual void AdjustAge ()
   {
      age = age * DOG_SPECIFIC_FACTOR + 5;
   }
...
}

Тогда в вызывающем коде вы бы просто сделали:
for (i = 0; i < ....)
     arr[i]->AdjustAge();

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


Albert Holguin

Виртуальный метод был бы подходом, который я использовал бы для такого типа проблем. +5 за список подходов к решению задачи...

Рейтинг:
1

Richard MacCutchan

C++ не имеет никакого механизма для обнаружения типов классов во время выполнения. Вам нужно будет добавить некоторые дополнительные свойства к вашим классам. В качестве альтернативы есть некоторые сторонние библиотеки,которые могут помочь; Google для "отражения C++".

Благодаря Карло я теперь знаю правильный ответ.