2015-04-18 2 views
2

Я попытался проверить указатель на какой тип был принят в качестве аргумента следующим образом:Как проверить тип во время выполнения?

#include <iostream> 
struct A{}; 
struct B:A{}; 
struct C:A{}; 
C *c = new C; 
B *b = new B; 
A *a = new A; 
void foo (A *a) 
{ 
    if(dynamic_cast<B*>(a)) 
    { 
     std::cout << "Type is B*" << std::endl; 
    //cannot dynamic_cast 'a' (of type 'struct A*') to type 'struct B*' (source type is not polymorphic) 
    } 

    if(dynamic_cast<C*>(a)) 
    { 
     std::cout << "Type is C*" << std::endl; 
     //cannot dynamic_cast 'a' (of type 'struct A*') to type 'struct C*' (source type is not polymorphic) 
    } 
} 

Но даже не компилировать. Можно ли это сделать? Я имею в виду, чтобы определить, какой указатель на какой тип мы передали как аргумент функции?

+2

Вам нужна хотя бы одна функция 'virtual' в' A', проще всего объявить виртуальный деструктор. –

+0

@ πάνταῥεῖ Зачем? Как виртуальная функция помогает мне определить тип во время выполнения? Не вижу этого ... –

+0

В этом случае компилятор создает vtable, что необходимо для 'dynamic_cast'. –

ответ

1

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

struct A 
{ 
    virtual ~A() {} 
}; 

Тогда:

int main() 
{ 
    foo(b); 
    foo(c); 
    return 0; 
} 

Выход:

Type is B* 
Type is C* 

Попробуйте здесь: link.

О, и я знаю, это только пример кода, но эти глобальные переменные, созданные с помощью new, выглядят ужасно.

+0

Сторона Примечание. Виртуальный деструктор - это хорошо, если вы производят классы с собственными ресурсами. Он обеспечивает надлежащее уничтожение производного класса при удалении указателя базового класса. –

+0

Я точно знаю, в чем цель виртуального деструктора, так в чем смысл? Даже если мы добавим виртуальную функцию-член, мы, скорее всего, объявим деструктор как виртуальную * в любом случае *, потому что это очень распространенная практика. –

Смежные вопросы