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

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

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

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 19.07.2011, 07:06   #1
Сtrl
C++
Форумчанин
 
Аватар для Сtrl
 
Регистрация: 27.03.2011
Сообщений: 803
По умолчанию Полиморфизм. Идентификация класса-наследника

Рассмотрим простой код:
Код:
struct Base abstract {};
struct Derived1:public Base {};
struct Derived2:public Base {};
/*...*/
Base *pObj = 0;
if (/*...*/)
	pObj = new Derived1;
else
	pObj = new Derived2;
Вопрос: как мне теперь определить, на объект какого типа указывает pObj? На объект типа Derived1 или Derived2?
Ищете информацию по C++?
cplusplus.com

Последний раз редактировалось Сtrl; 19.07.2011 в 07:59.
Сtrl вне форума Ответить с цитированием
Старый 19.07.2011, 07:58   #2
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Если у Base будет виртуальная функция, например, чисто виртуальный деструктор, т.е.Base предполагается абстрактым, то можно через dynamic_cast. Не забыть только включить поддержку rtti.
Код:
if (dynamic_cast<Derived1*>(pObj))
{
}
else if (dynamic_cast<Derived2*>(pObj))
{
}

Последний раз редактировалось EUGY; 19.07.2011 в 08:01.
EUGY вне форума Ответить с цитированием
Старый 19.07.2011, 08:02   #3
Сtrl
C++
Форумчанин
 
Аватар для Сtrl
 
Регистрация: 27.03.2011
Сообщений: 803
По умолчанию

Все, вроде сообразил - dynamic_cast возвращает нулевой указатель, если преобразование невозможно. Спасибо.
А поддержка RTTI в настройках компилятора включается, или где?
Ищете информацию по C++?
cplusplus.com
Сtrl вне форума Ответить с цитированием
Старый 19.07.2011, 08:06   #4
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Цитата:
Сообщение от Сtrl Посмотреть сообщение
Все, вроде сообразил - dynamic_cast возвращает нулевой указатель, если преобразование невозможно. Спасибо.
А поддержка RTTI в настройках компилятора включается, или где?
Так точно.

У меня в MS VS есть ключ (/GR)
EUGY вне форума Ответить с цитированием
Старый 19.07.2011, 08:08   #5
_-Re@l-_
C++, Java
Старожил
 
Аватар для _-Re@l-_
 
Регистрация: 10.04.2010
Сообщений: 2,665
По умолчанию

Можно так ешё
Код:
void fn(Base* p)
{
    const type_info& ti = typeid(*p);
    if (ti == typeid(Base))
    {
         // Это объект типа Base
    }
    else if (ti == typeid(Derived))
    {
        // Это объект типа Derived
    }
}
Ну, суть такая.

Последний раз редактировалось _-Re@l-_; 19.07.2011 в 08:13.
_-Re@l-_ вне форума Ответить с цитированием
Старый 19.07.2011, 08:11   #6
Сtrl
C++
Форумчанин
 
Аватар для Сtrl
 
Регистрация: 27.03.2011
Сообщений: 803
По умолчанию

Я пробовал так. Во-первых, сравнение - это ==, а не =. Во-вторых, не знаю как typeid должен работать, но в моей студии он определяет тип по типу указателя, а не самого объекта. Может, это потому что я RTTI не включал (как EUGY выше сказал).
Ищете информацию по C++?
cplusplus.com
Сtrl вне форума Ответить с цитированием
Старый 19.07.2011, 08:14   #7
_-Re@l-_
C++, Java
Старожил
 
Аватар для _-Re@l-_
 
Регистрация: 10.04.2010
Сообщений: 2,665
По умолчанию

Опсть, прошу прощения, да, вы правы, просто только проснулся, даже не вижу что пишу

Последний раз редактировалось _-Re@l-_; 19.07.2011 в 08:18.
_-Re@l-_ вне форума Ответить с цитированием
Старый 19.07.2011, 08:21   #8
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Скажу несколько не в тему, но все же.
В MFC (при всей моей не любви) оригинально организована rtti для своих объектов через DECLARE_DYNAMIC. Помнится, когда изучал, получил интеллектуальное наслаждение.
EUGY вне форума Ответить с цитированием
Старый 19.07.2011, 08:36   #9
Сtrl
C++
Форумчанин
 
Аватар для Сtrl
 
Регистрация: 27.03.2011
Сообщений: 803
По умолчанию

_-Re@l-_, EUGY, оба ваших метода работают, только нужно, чтобы была хоть одна виртуальная функция. Еще раз спасибо! Кстати, я макрос написал для проверки типа:
Код:
#define TYPE_ASSIGN(POINTER, TYPE) (dynamic_cast<TYPE*>(POINTER) != 0)
Можно его как-то заменить на функцию? Все-таки макросы - это не очень хорошо.
Ищете информацию по C++?
cplusplus.com
Сtrl вне форума Ответить с цитированием
Старый 19.07.2011, 10:25   #10
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

Сtrl

Можно его как-то заменить на функцию? Все-таки макросы - это не очень хорошо.

монопенисуально.

Код:
template <typename T, typename U>
bool IsTypeOfClass(U* u)
{
	return dynamic_cast<T*>(u) != NULL;
}
PS. По теме: весь этот велосипед, который ты изобрёл - не нужен. То есть вообще. Полиморфизм и паттерны (например Visitor) рулят.
Rififi вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Где найти наследника от TreeView с привязкой к набору данных? Greek9000 Общие вопросы .NET 3 18.05.2011 07:57
конструктор наследника абстрактного класса tiger() Visual C++ 5 15.05.2011 07:16
Netbeans редактирование фрейма из класса не наследника Nicko_mt Общие вопросы по Java, Java SE, Kotlin 3 19.04.2011 15:35
[B]Написать наследника компонента. Delphi.[/B] OnCreate Помощь студентам 0 19.10.2010 22:44
Создание наследника ImmortalAlexSan Общие вопросы Delphi 4 29.04.2010 14:19