虚函数无敌解释

转载 2012年07月14日 19:59:30

助于理解。。。

虚拟函数(virtual)
  使用面向对象的开发过程就是在不断的抽象事物的过程,我们的目标就是抽象出一个紧内聚,低偶合,易于维护和扩展的模型.但是在抽象过程中我们会发现很多事物的特征不清楚,或者很容易发生变动,怎么办呢?比如飞禽都有飞这个动作,但是对于不同的鸟类它的飞的动作动方式是不同的,有的要滑行,有的要颤抖翅膀, 虽然都是飞但千差万别,在我们抽象的模型中不可能一个个都考虑到,怎么为以后留下好的扩展,怎么来处理子类的前差万别?比如我现在又要抽象一个类"鹤", 它也有飞禽的特征,我可以简单的继承"飞禽",而不去修改现有的代码,可以很容易的扩展系统
  面向对象的概念中引入了虚拟函数. 就是在父类中把子类中共同的,易于变化或者不清楚的特征抽取出来,作为子类需要去重新实现的操作(override),我们可以称做"热点".还是上面的例子
  class 飞禽
  { 
    private void Shape ;    //注意private访问修订符,Shape是不会被子类继承的!
    public string Wing ;    //翅膀
    public string Feather ; //羽毛  
    public virtual boolean Fly() {} ;  //飞翔. 定义的虚拟函数, 这是一个热点
  }
 
  class 麻雀 : 飞禽    //麻雀从飞禽继承而来
  {
    public boolean CanSpeaking; //申明了麻雀自己的特征.
    public override boolean Fly() {...} ;    //重载飞翔动作,实现自己的飞翔
  }

  class  鹤 : 飞禽  //鹤从飞禽继承而来
  {
   
    public override void Fly() {...} ;    //重载实现鹤的飞翔
  }
 
  //如何来使用虚拟函数,这里同时也是一个多态的例子.
  //打鸟
  void ShootBird(Bird : 飞禽)  //注意这里申明传入一个"飞禽"类,而不是具体的"鸟类". 好处是以后不管出现多少种鸟类,只要是从飞禽继承下来的,都照打不误:)
  {
    if( Bird.fly())
    {
      ....
      开始打鸟...
      ...
    }
  }
 
  static void main()
  {
     //打麻雀
     ShootBird( new 麻雀());
     //打鹤
     ShootBird( new 鹤());    
     //看到没!都是打鸟的过程,我这里可以实现打任何一种鸟了,添加一行代码而不去修改代码
     ShootBird( new 其它的飞禽());         
     ShootBird( ...);         
  }  
-------------------------------------------- 
虚拟函数的的执行过程:   
   虚拟函数从C#的程序编译的角度来看,它和其它一般的函数有什么区别呢?一般函数在编译期间就静态的编译到了执行文件中,在程序运行期间是不发生变化的,也就是写死了!而虚拟函数在编译期间是不被静态编译的,它是不确定的,它会根据运行时期对象实例来动态判断要调用的函数,其中那个申明时定义的类叫申明类,那个执行时实例化的类叫实例类.具体的检查的流程如下:
 a.当调用一个对象的函数时,系统会去检查这个对象申明定义的类,即申明类
 b.然后它更据这个申明类型的定义去检查这个函数是否虚拟函数
 c.如果有virtual关键字,他就认为是虚拟函数,这个时候他又去检查实例类.
 d.好!找到这个实例类后,他再检查这个实例类定义中是否重新实现了虚拟函数(通过override),如果是!好了他就不再找了,马上执行它.
 e.如果没有,系统又往上层父类找实例类的父类,直到找到一个最近重载了该虚拟函数的父类为止,然后执行该函数.
 呵呵,知道这点有什么用呢?搞清楚这个老师的bt题目就可以拿下了.
 还是来个简单例子说明问题
 class A
 {
   protected virtual FuncA() {Console.WriteLine("FuncA")} ;//注意virtual,表明这是一个虚拟函数
 }
 
 class B :A             //注意 B是从A类继承,所以A是父类,B是子类
 {
   protected override FuncA(){Console.WriteLine("FuncB")} ; //注意override ,表明重新实现了虚拟函数
 }
 
 static void main()
 {
   A a ;               //定义一个a这个A类对象.这个A就是a的申明类
   A b ;               //定义一个b这个A类的对象.这个A就是b的申明类 
   a = new A() ;      //实例化a对象,A是这次实例类
   a.FuncA() ;        //开始执行FuncA. 1.先照申明类A 2.检查是虚拟方法 3.检查实例类A 4.执行实例类中的方法 5输出结果 FuncA
   b = new B();     //实例化b对象,B是这次实例类
   b.FuncA() ;     //开始执行FuncA. 1.先照申明类A 2.检查是虚拟方法 3.检查实例类B  4.执行实例类中的方法 5输出结果 FuncB
 }  


from:http://forum.mvpcn.net/ShowPost.asp?action=Previous&id=113

关于虚函数和多态(很好的解释)

C++:派生类中重定义基类的成员函数与虚函数区别在哪里?
  • foreverhuylee
  • foreverhuylee
  • 2014年07月17日 12:15
  • 2096

终于明白了虚函数、纯虚函数和接口的实用方法和意义

从理论上来说,这三个概念很容易背的滚瓜烂熟,但是从大学毕业到现在,我都没真正搞明白这三个东西的出现,究竟是为了做到什么事情。 也许之前我很少写代码,更很少写面向对象的代码,即使有写多半也很容易写回到...
  • huangyimo
  • huangyimo
  • 2016年01月08日 08:55
  • 6818

虚函数调用过程

1.(mov ecx,dword ptr [ebp-0Ch])将this指针压入ecx 2.(mov edx,dword ptr [ecx])this指针指向该对象的首地址,而该处的前四个字节存放着...
  • w616589292
  • w616589292
  • 2016年03月15日 15:54
  • 1264

虚函数、虚指针和虚表

虚函数、虚指针和虚表 http://eriol.iteye.com/blog/1167737 关于虚函数的背景知识 用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成...
  • coolshine1234
  • coolshine1234
  • 2013年12月18日 09:49
  • 5887

虚函数和纯虚函数的作用与区别

虚函数为了重载和多态的需要,在基类中是有定义的,即便定义是空,所以子类中可以重写也可以不写基类中的此函数! 纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数! 虚函数 ...
  • xwpc702
  • xwpc702
  • 2013年03月13日 19:28
  • 42318

什么是C++虚函数、虚函数的作用和使用方法

转自:http://c.biancheng.net/cpp/biancheng/view/244.html 我们知道,在同一类中是不能定义两个名字相同、参数个数和类型都相同的函数的,否则就是...
  • csCrazybing
  • csCrazybing
  • 2016年09月19日 12:53
  • 670

为什么要用虚函数?什么时候用虚函数?

刚开始学C++学到“类”这一章的时候一直不明白虚函数用来做什么。看书上举的例子不太明白。 #include using namespace std; class Father { public: ...
  • CharlesSimonyi
  • CharlesSimonyi
  • 2013年04月16日 22:25
  • 5591

关于C++虚函数和纯虚函数

虚函数为了重载和多态的需要,在基类中是由定义的,即便定义是空,所以子类中可以重写也可以不写基类中的函数! 纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数! 虚...
  • pamchen
  • pamchen
  • 2013年03月06日 12:05
  • 999

C++ 虚函数 重载 重写的区别(转)

版权声明:本文转自http://blog.csdn.net/hackbuteer1/article/details/7475622  C++编程语言是一款应用广泛,支持多种程序设计的计算机编程语...
  • Primeprime
  • Primeprime
  • 2016年03月04日 00:29
  • 3835

1074. 宇宙无敌加法器(20)

1074. 宇宙无敌加法器(20)PAT Basic 9月17日真题 地球人习惯使用十进制数,并且默认一个数字的每一位都是十进制的。而在PAT星人开挂的世界里,每个数字的每一位都是不同进制的,这种神...
  • weixin_40411846
  • weixin_40411846
  • 2017年09月29日 09:39
  • 270
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:虚函数无敌解释
举报原因:
原因补充:

(最多只允许输入30个字)