2015-04-18 137 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

“A”中至少需要一个'virtual'函数,最简单的是声明一个虚拟析构函数。 –

+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

我完全知道,虚拟析构函数的目的是什么,所以有什么意义?即使我们添加虚拟成员函数,我们也很可能将析构函数声明为virtual *,因为这是非常普遍的做法。 –