码迷,mamicode.com
首页 > 编程语言 > 详细

C++——使用RTTI为继承体系编写"=="运算符

时间:2014-10-09 02:59:57      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   使用   ar   strong   

有下面一个继承体系,我们需要为其添加"=="操作符,该怎么办呢 ??

class Animal
{

};

class Cat : public Animal
{

};

class Dog : public Animal
{

};

如果我们为每个类重载"=="运算符,那么我们还需要重载子类与基类之间的"=="运算符,这样代码实现起来是很恐怖的。
我们可以尝试,只为基类重载一个"=="运算符,然后在基类中实现一个虚函数equal,在子类中去实现它。

实现代码如下:

bubuko.com,布布扣
 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;
10 };
11 
12 class Cat : public Animal
13 {
14 public:
15     bool equal(const Animal &other) const
16     {
17         //Cat Animal
18         if(const Cat *pc =  dynamic_cast<const Cat*>(&other)) 
19         {
20             return name_ == pc->name_;
21         }
22         return false;
23     }
24 
25 private:
26     string name_;
27 };
28 
29 class Dog : public Animal
30 {
31 public:
32     bool equal(const Animal &other) const
33     {
34         //Dog Animal
35         if(const Dog *pd = dynamic_cast<const Dog*>(&other))
36         {
37             return name_ == pd->name_;
38         }
39         return false;
40     }
41 private:
42     string name_;
43 };
44 
45 bool operator==(const Animal &a, const Animal &b)
46 {
47     return typeid(a) == typeid(b) && a.equal(b);
48 }
49 
50 int main(int argc, char const *argv[])
51 {
52 
53     Cat c;
54     Dog d;
55 
56     Animal *pa = &c;
57     cout << (*pa == c) << endl;
58     pa = &d;
59     cout << (*pa == d) << endl;
60     return 0;
61 }
View Code

在重载操作中:

bool operator==(const Animal &a, const Animal &b)
{
    return typeid(a) == typeid(b) && a.equal(b);
}

  typeid是一种类型识别运算符,如果要识别的类型不是class或不含有virtual函数,那么在编译期间自动识别,typeid指出静态类型,如果class中含有virtual函数,那么typeid在运行期间识别类型。
  对equal的调用,显然使用了动态识别,总是能根据对象的实际类型,调用对应的equal版本。

在equal函数中,dynamic_cast使得对象进行了"向下塑形",static_cast与dynamic_cast之间有一些不同:

  static_cast发生在编译期间,如果转化不通过,那么编译错误,如果编译无问题,那么转化一定成功。static_cast仍具有一定风险,尤其是向下塑形时,将Base*转化为Derived*时,指针可以转化,但是指针未必指向Derived对象。

  dynamic_cast发生在运行期间,用于将Base的指针或者引用转化为派生类的指针或者引用,如果成功,返回正常的指针或引用,如果失败,返回NULL(指针),或者抛出异常(bad_cast)

 

在"=="的重载中,我们保证了equal两个参数的类型相同,那么我们为何还需要在equal中“向下塑形”呢?

  equal有可能被单独使用,所以other的类型未必和自己相同。  

 

  如果不进行转换,other是无法访问name属性的,因为Animal中没有name。

 

 

typeid和dynamic_cast是实现RTTI的主要手段。

 

C++——使用RTTI为继承体系编写"=="运算符

标签:style   blog   http   color   io   os   使用   ar   strong   

原文地址:http://www.cnblogs.com/gjn135120/p/4012227.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!