首页 > 代码库 > C++ Primer 学习笔记_102_特殊工具与技术 --运行时类型识别[续]
C++ Primer 学习笔记_102_特殊工具与技术 --运行时类型识别[续]
特殊工具与技术
--运行时类型识别[续]
三.RTTI的使用
当比较两个派生类对象的时候,我们希望比较可能特定于派生类的数据成员.如果形参是基类引用,就只能比较基类中出现的成员,我们不能访问在派生类中但不在基类中出现的成员.
因此我们可以使用RTTI,在试图比较不同类型的对象时返回假(false)。
我们将定义单个相等操作符。每个类定义一个虚函数 equal,该函数首先将操作数强制转换为正确的类型。如果转换成功,就进行真正的比较;如果转换失败,equal 操作就返回 false。
1.类层次
class Base { friend bool operator==(const Base &,const Base &); public: // interface member for base private: virtual bool equal(const Base &) const; }; class Derived : public Base { friend bool operator==(const Derived &,const Derived &); public: // interface member for base private: virtual bool equal(const Base &) const; };
2.类型敏感的相等操作符
bool operator==(const Base &lhs,const Base &rhs) { return typeid(lhs) == typeid(rhs) && lhs.equal(rhs); }
3.虚函数equal
层次中的每个类都必须定义自己的equal版本.派生类中的equal函数将以相同的方式开始:将实参强制转换成为类本身的数据类型.
bool Derived::equal(const Base &rhs) const { //必须将其转换成为指针类型,其原因请参考上一篇C++ Primer博客 if (const Derived *dp = dynamic_cast<const Derived *>(&rhs)) { // compare two Derived objects and return result } return false; }
4.基类equal函数
bool Base::equal(const Base &rhs) const { // compare two Base objects and return result }
使用形参之前不必强制转换,*this和形参都是Base对象,所以对形参类型也定义了该对象的所有操作.
四.type_info类
type_info支持的操作 | |
t1 == t2 | 如果两个对象 t1 和 t2 类型相同,就返回 true;否则,返回false |
t1 != t2 | t1 != t2 如果两个对象 t1 和 t2 类型不同,就返回 true;否则,返回false |
t.name() | t.name() 返回 C 风格字符串,这是类型名字的可显示版本。类型名字用系统相关的方法产生 |
t1.before(t2) | 返回指出 t1 是否出现在 t2 之前的 bool 值。before 强制的次序与编译器有关 |
因为打算作基类使用,type_info 类也提供公用虚析构函数。如果编译器想要提供附加的类型信息,应该在 type_info 的派生类中进行。
默认构造函数和复制构造函数以及赋值操作符都定义为 private,所以不能定义或复制 type_info 类型的对象。 程序中创建 type_info 对象的唯一方法是使用 typeid 操作符。
name 函数为 type_info 对象所表示的类型的名字返回 C 风格字符串。给定类型所用的值取决于编译器,具体来说,无须与程序中使用的类型名字匹配。对 name 返回值的唯一保证是,它为每个类型返回唯一的字符串。虽然如此,仍可以使用 name 成员来显示 type_info 对象的名字:
int iobj; cout << typeid(iobj).name() << endl; cout << typeid(8.16).name() << endl; cout << typeid(std::string).name() << endl; cout << typeid(Base).name() << endl; cout << typeid(Derived).name() << endl;
G++编译器显示:
注:name返回的格式和值随编译器而变化.type_info类随编译器而变.一些编译器提供的附加的成员函数,那些函数提供关于程序中所用类型的附加信息.
//P653 习题18.20 class A {}; class B : public A {}; class C : public B {}; int main() { A *pa = new C(); cout << typeid(*pa).name() << endl; //1A cout << typeid(pa).name() << endl; //P1A C cobj; A &ra = cobj; cout << typeid(&ra).name() << endl; //P1A cout << typeid(ra).name() << endl; //1A B *px = new B; A &raTest = *px; cout << typeid(raTest).name() << endl; //1A }