虚函数机制理解

来源:互联网 发布:宫刑 知乎 废除 编辑:程序博客网 时间:2024/06/06 09:04

再次翻阅深度探索C++对象模型,算是对虚函数机制又多了一层理解了。以例子说明

  1. class ZooAnimal  
  2. {  
  3.  public:      
  4.     ZooAnimal();  
  5.     virtual ~ZooAnimal();  
  6.     virtual void animate();  
  7.     virtual void draw();  
  8.     // ....  
  9.  private:  
  10.     // ZooAnimal的animate()和draw()所需要的数据  
  11. };  
  12.   
  13. class Bear: public ZooAnimal  
  14. {  
  15.  public:  
  16.     Bear();  
  17.     void animate();   // 虽然没有显式表明是virtual,但是从基类继承virtual属性  
  18.     void draw();     //  虽然没有显式表明是virtual,但是从基类继承virtual属性  
  19.     virtual void dance();  
  20.     // ....  
  21.  private:  
  22.     // Bear的animate()和draw()以及dance()需要的数据  
  23. };  

上面定义了ZooAnimal类和Bear类,我们来解释下在以下两种情况中编译器会做哪些操作:

例1:

Bear yogi;

ZooAnimal franny = yogi ; 

例2:

Bear yogi;

ZooAnimal *franny = &yogi;

在上面两个例子中,我们要是同时调用franny.draw() 会发生什么情况呢?

在例1中,实际上是调用的ZooAnimal 类版本的draw函数,而在例2中,将调用Bear类版本的ZooAnimal函数。

原因是:

例1中相当于执行的合成的复制构造函数的操作,在复制构造函数中,会显示设定对象franny的vptr指向ZooAnimal class 的virtual table。

例2中相当于进行了指针的强制类型转换,而指针的强制类型转换的本质就是截取地址的多大部分,具体原理请参见:http://blog.sina.com.cn/s/blog_4e967c8b0100zh6h.html


以上可知要触发动态绑定,必须满足两个条件:第一:只有指定为虚函数的成员函数才能进行动态绑定。第二,必须通过基类类型的引用或者指针进行函数调用。举例:

    double print_total(const Item_base&, size_t);

           Item_base item;

           print_total(item, 10); // OK 

           Bulk_item bulk;

           print_total(bulk, 10); // OK  引用bulk中Item_base的部分。

          Item_base *item = &bulk; // OK , 指针指向bulk 的Item_base部分。




        

原创粉丝点击