A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 邢义敏 中级黑马   /  2013-2-21 20:22  /  1566 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 邢义敏 于 2013-2-22 11:44 编辑

今天看到了一篇文,里面写到了虚函数和纯虚函数,我没有看明白,能给我解释一下他俩的意义,他俩有什么区别,一般都是什么时候用到的,最好能够举例说明一下,谢谢啦

4 个回复

倒序浏览
Java中没有虚函数,所谓C++中的虚函数就是Java中的普通方法。
C++中的纯虚函数就是Java中抽象方法。

对于Java中普通方法和抽象方法,你还是多看视频吧
回复 使用道具 举报
1:java中没有虚函数的概念,但是有抽 象函数的概念,用abstract关键字表示,java中抽象函数必须在抽象类中,而且抽象 函数不能有函数体,抽象类不能被实例化,只能由其子类实现抽象函数,如果某个抽象类的子类仍是抽象类,那么该子类不需要实现其父类的抽象函数。

2:C++中的有虚函数的概念,用virtual 关键字来表示,每个类都会有一个虚函数表,该虚函数表首先会从父类中继承得到父类的虚函数表, 如果子类中重写了父类的虚函数(不管重写后的函数是否为虚函数),要调用哪个虚函数,是根据当前实际的对象来判断的(不管指针所属类型是否为当前类,有可 能是父类型),指针当前指向的是哪种类型的对象,就调用哪个类型中类定义的虚函数。每个类只有一张虚拟函数表,所有的对象共用这张表。
C++的函数多态就是通过虚函数来实现的。
3:C++中,如果函数不是虚函数,则调用某个函数,是根据当前指针类型来判断的,并不是根据指针所指向对象的类型。
4:Java中,如果函数不是抽象函数,而是一个普通函数,它是默认实现类似C++中虚函数功能的,也就是说,调用某个函数,是根据当前指针所指向对象的类型来判断的,而不是根据指针类型判断。正好与C++中的普通函数相反。即:JAVA里自动实现了虚函数。
C++ Java
虚函数 -------- 普通函数
纯虚函数 -------- 抽象函数
抽象类 -------- 抽象类
虚基类 -------- 接口
纯虚函数: 主要特征是不能被用来声明对象,是抽象类,是用来确保程序结构与应用域的结构据具有直接映射关系的设计工具。带有纯虚函数的类称为抽象类,抽象类能被子类 继承使用,在子类中必须给出纯虚函数的实现,如果子类未给出该纯虚函数的实现,那么该子类也是抽象类,只有在子类不存在纯虚函数时,子类才可以用来声明对 象!抽象类也能用于声明指针或引用,或用于函数声明中。具有抽象类特性的类还有构造函数和析构函数,全部是保护的类。如果没有给出纯虚函数的实现,则在它 所在的类的构造函数或析构函数中不能直接或间接的调用它。纯虚函数的实现可以在类声明外进行定义。


5. C++中一般都是把析构函数声明为虚函数。因为虚函数可以实现动态绑定,也就是到底调用哪个函数是根据指针当前指向哪个对象来确定的,不是根据指针的类型 来确定。如果C++中不把析构函数声明为虚函数,那么其有个子类,重写了虚函数,那么当父类指针指向一个子类对象时,当调用析构函数时,只调用父类的析构 函数,而无法调用子类的析构函数,所以一般情况是把析构函数声明为虚函数,实现动态绑定。当然如果一个类不包含虚函数,这经常预示不打算将它作为基类使 用。当一个类不打算作为基类时,将析构函数声明为虚拟通常是个坏主意。
标准 string 类型不包含虚函数,如果把String作为基类继承得到子类会出问题。
总之:多态基类应该声明虚析构函数。如果一个类有任何虚函数,它就应该有一个虚析构函数;如果不是设计用于做基类或不是设计用于多态,这样的类就不应该声明虚析构函数。

点评

了解了,O(∩_∩)O谢谢  发表于 2013-2-22 11:43
回复 使用道具 举报
黑马-张洋 发表于 2013-2-21 20:37
1:java中没有虚函数的概念,但是有抽 象函数的概念,用abstract关键字表示,java中抽象函数必须在抽象类中 ...

学习了,受教了
回复 使用道具 举报
翻了下C++笔记,未必正确,仅供参考,希望能帮到你。

      虚函数的原理,可以这么理解:在java中,子类中的函数如果没有重载的话,默认会调用父类的方法,如果声明了虚函数,则不调用父类方法。
      虚函数的定义机制:在C++中,使用关键字virtual声明函数为虚函数。当类中定义有虚函数时,编译器会将该类中所有虚函数的首地址保存在一张地址表中,
这张表被称为虚函数地址表,简称虚表。同时,编译器还会在类中添加一个隐藏数据成员,称为虚表指针。该指针中保存着虚表的首地址,用于记录和查找虚函数。
      
      至于纯虚函数,它和虚函数没多大关系,可以理解为不能实例化的类,至于这么做的作用,一般认为有两个:
      1.为了安全.因为避免任何需要明确但是因为不小心而导致的未知的结果.  提醒子类去做应做的实现.  
      2.为了效率,不是程序执行的效率,而是为了编码的效率.virtual=0;
      纯虚函数的定义机制:virtual=0;

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马