C++开发中级
993 浏览 5 years, 11 months
6.6 运行时类型工具
版权声明: 转载请注明出处 http://www.codingsoho.com/运行时类型工具
相对于其他面向对象语言,C++以编译期为主。您在前面已经知道,重写方法是可行的,这是由于方法以及实现之间的间隔,而不是由于对象有关于自身所属类的内建信息。
然而在C++中,有些特性提供了对象的运行时视角。这些特性通常归属于一个名为运行时类型识别(Run Time Type Information. RTTI)的特性集。RTTI提供了许多有用的特性判断对象所属的类。
其中一种特性是前面说过的dynamic_cast
,可以在OO层次结构中进行安全的类型转换。
RTTI的第二个特性是typeid
运算符,这个运算符可以让您在运行时查询对象从而判别对象的类型。多数情况下,不应该使用typeid,因为最好用虚方法处理基于对象类型运行的代码。下面的代码使用了typeid,根据对象的类型输出消息:
#include <typeinfo>
void speak(const Animal& inAnimal)
{
if(typeid(inAnimal) == typeid(Dog&)){
cout << "Woof!" << endl;
}else if(typeid(inAnimal) == typeid(Bird&)){
cout << "Chirp!" << endl;
}
}
一旦看到这样的代码,应该立即考虑用虚方法重新实现该功能。在此情况下,更好的实现是在Animal类中声明一个名为speak()的虚方法。Dog会重写这个方法,输出”Woof !”,Bird也会重写这个方法,输出’'Chirp !”。这种方法更适合面向对象程序,会将与对象有关的功能给予这些对象。
提示:当存在多态性时,类至少应该有一个虚方法,这样typeid运算符才能正常运行。
typeid运算符的主要价值之一在于日志以及调试。下面的代码将typeid用于日志。logObject函数将“可记录”对象作为参数。设计是这样的:任何可被记录的对象都从Loggable对象继承,都支持一个名为getLogMessage()的方法。这样,Loggable就是一个混入类。
#include <typeinfo>
void logObject(Loggable& inLoggableObject)
{
logfile << typeid(inLoggableObject).name() << " ";
logfile << inLoggableObject.getLogMessage() << endl;
}
logObject()函数首先将对象所属类的名称写入文件,随后是日志信息。如果使用了这种方法,当您在后来阅读日志的时候,就可以看出文件每一行涉及的对象。
如果您不是为了日志记录或者调试,应该考虑用虚方法替代typeid。