15.4.2 RTTI的工作原理(2)
否则,结果为0,即空指针。
程序清单15.17演示了这种处理。首先,它定义了3个类,名称为Grand、Superb和Magnificent。Grand类定义了一个虚函数Speak( ),而其他类都重新定义了该虚函数。Superb类定义了一个虚函数Say( ),而Manificent也重新定义了它(参见图15.4)。程序定义了GetOne( )函数,该函数随机创建这3种类中某种类的对象,并对其进行初始化,然后将地址作为Grand*指针返回(GetOne( )函数模拟用户做出决定)。循环将该指针赋给Grand *变量pg,然后使用pg调用Speak( )函数。因为这个函数是虚拟的,所以代码能够正确地调用指向的对象的Speak( )版本。
然而,不能用相同的方式(即使用指向Grand的指针)来调用Say( )函数,因为Grand类没有定义它。然而,可以使用dynamic_cast运算符来检查是否可将pg的类型安全地转换为Superb指针。如果对象的类型为Superb或Magnificent,则可以安全转换。在这两种情况下,都可以安全地调用Say( )函数:
赋值表达式的值是它左边的值,因此if条件的值为ps。如果类型转换成功,则ps的值为非零(true);如果类型转换失败,即pg指向的是一个Grand对象,ps的值将为0(false)。程序清单15.17列出了所有的代码。顺便说一句,有些编译器可能会对无目的赋值(在if条件语句中,通常使用= =运算符)提出警告。
|
| (点击查看大图)图15.4 Grand类系列 |
程序清单15.17 rtti1.cpp