运行时类型识别
允许在运行时通过基类指针(或引用)辨别对象所属的具体派生类; 只对多态类型适用; 比虚函数动态绑定的开销更大,因此应仅对虚函数无法解决的问题使用。
运行时类型识别的方式
用dynamic_cast做类型转换的尝试; 用typeid直接获取类型信息。
dynamic_cast的使用:
语法形式
dynamic_cast<目的类型>(表达式)
功能
将基类指针转换为派生类指针,将基类引用转换为派生类引用; 转换是有条件的 如果指针(或引用)所指对象的实际类型与转换的目的类型兼容,则转换成功进行; 否则如执行的是指针类型的转换,则得到空指针;如执行的是引用类型的转换,则抛出异常。
例:
#include <iostream>
using namespace std;
class Base {
public:
virtual void fun1() { cout << "Base::fun1()" << endl; }
virtual ~Base() { }
};
class Derived1: public Base {
public:
virtual void fun1() { cout << "Derived1::fun1()" << endl; }
virtual void fun2() { cout << "Derived1::fun2()" << endl; }
};
class Derived2: public Derived1 {
public:
virtual void fun1() { cout << "Derived2::fun1()" << endl; }
virtual void fun2() { cout << "Derived2::fun2()" << endl; }
};
void fun(Base *b) {
b->fun1();
//尝试将b转换为Derived1指针
Derived1 *d = dynamic_cast<Derived1 *>(b);
//判断转换是否成功
if (d != 0) d->fun2();
}
int main() {
Base b;
fun(&b);
Derived1 d1;
fun(&d1);
Derived2 d2;
fun(&d2);
return 0;
}
typeid的使用:
语法形式
typeid ( 表达式 )
typeid ( 类型说明符 )
功能
获得表达式或类型说明符的类型信息
表达式有多态类型时,会被求值,并得到动态类型信息; 否则,表达式不被求值,只能得到静态的类型信息。 类型信息用type_info对象表示,type_info是typeinfo头文件中声明的类; typeid的结果是type_info类型的常引用; 可以用type_info的重载的“==”、“!=”操作符比较两类型的异同; type_info的name成员函数返回类型名称,类型为const char *。
例:
#include <iostream>
#include <typeinfo>
using namespace std;
class Base {
public:
virtual ~Base() { }
};
class Derived: public Base { };
void fun(Base *b) {
//得到表示b和*b类型信息的对象
const type_info &info1 = typeid(b);
const type_info &info2 = typeid(*b);
cout << "typeid(b): " << info1.name() << endl;
cout << "typeid(*b): " << info2.name() << endl;
if (info2 == typeid(Base)) //判断*b是否为Base类型
cout << "A base class!" << endl;
}
int main() {
Base b;
fun(&b);
Derived d;
fun(&d);
return 0;
}