• C++ RTTI的使用


    这里我们给出一个使用RTTi的例子;

    考虑一个类层次,我们希望为它实现 operator==相等操作符:如果两个对象的给定数据成员集合的值相同,则它们就相等。

    每个派生类可以增加自己的成员,当然,测试相等的时候也要包含这些数据。

    对于类层次中有两个类型(一个基类,一个派生类),按照一般的方法,我们就需要实现以下四个函数。

    bool operator==(const Base&, const Base&bool operator==(const Derived&, const Derived&bool operator==(const Base&, const Derived&bool operator==(const Derived&, const Base&)

    但是如果类层次中有几个类型,必须定义的操作符的数目就迅速扩大---3个类型需要9个操作符,4个类型就需要16个操作符~~
    那么,我们有没有较好的办法来解决这一问题呢?这里我们采用RTTi

    只重载一个Animal基类的==操作符
    为每个类(包括派生类)实现 equal函数,这是一个虚函数。

    在编写代码之前,我们要搞清楚,两个类相等 的前提是 首先它们的类型相同,其次它们的成员也相同
    在这里,首先做几点说明,以下的类中,Animal是基类,Cat,Dog是其派生类。

    代码如下:

     1 #include <iostream>
     2 #include <typeinfo>
     3 #include <string>
     4 using namespace std;
     5 
     6 class Animal
     7 {
     8     public:
     9         virtual bool equal(const Animal &other)const = 0;11 };
    12 
    13 class Cat:public Animal
    14 {
    15     public:
    16         bool equal(const Animal &other)const
    17         {
    18             if(const Cat *pc = dynamic_cast<const Cat*>(&other))
    19             { return name_ == pc->name_; }
    20             return false; 
    21         }
    22     private:
    23         string name_;
    24 };
    25 
    26 class Dog:public Animal
    27 {
    28     public:
    29         bool equal(const Animal &other)const
    30         {
    31             if(const Dog *pd = dynamic_cast<const Dog*>(&other))
    32             { return name_ == pd->name_; }
    33             return false;
    34         }
    35     private:
    36         string name_;
    37 };
    38 
    39 bool operator==(const Animal &a, const Animal &b)
    40 {
    41     return typeid(a)==typeid(b)&&a.equal(b);
    42 }
    43 
    44 
    45 int main(int argc, const char *argv[])
    46 {
    47     Cat c;
    48     Dog d;
    49     Animal *pa = &c;
    50    
    51     cout <<( *pa == c) << endl;//1
    52     cout <<( *pa == d) << endl;//0
    53     return 0;
    54 }

    这里我们做以下几点说明;

    首先是==operator的重载 

    1 bool operator==(const Animal &a, const Animal &b)//Animal中有虚函数
    2 {
    3      return typeid(a)==typeid(b)&&a.equal(b);//运行时绑定
    4 }

    这里利用了&&的短路特性,即:如果两个对象的类型不同(Cat,Dog),那么该语句直接返回false,不再继续比较后面的条件。

    然后我们再看Cat中的equal函数:

     bool equal(const Animal &other)const
            {
                if(const Cat *pc = dynamic_cast<const Cat*>(&other))
                { return name_ == pc->name_; }
                return false; 
            }   

    if语句中用到了dynamic_cast 强制转换,而这个强制转换总是成功的,那么这个强制转换还是必要的吗?答案是肯定的。原因如下:

    如果不进行强制转换,那么可能造成不能访问函数的右操作数的派生类成员。例如other类为Animal,若不进行“向下塑形(运行时绑定)”转化,则otherr不能访问Cat的成员name_。
  • 相关阅读:
    PetShop数据访问层之消息处理 《解剖PetShop》系列之三
    正则过滤汉字
    c语言 断点续传3
    c 写cgi 与socket通信
    C 语言 断点续传2
    承接B2C商城定制开发 空间+域名+风语商城系统=¥4000
    16进制 SQL注入
    c# socket传送大文件
    c写cgi cookies 设置与读取
    cgi 操作封装
  • 原文地址:https://www.cnblogs.com/xfxu/p/4012383.html
Copyright © 2020-2023  润新知