本文不讨论虚函数的原理,只简单总结下虚函数的常用事项。

虚函数(虚方法)是C++动态联编 实现多态的重要手段,在函数声明时使用关键字virtual即可,如: virtual void func(void);

注意:虚函数(虚方法)只针对类的成员函数,普通函数不可声明为虚函数!且一般只有在用到继承时才将基类的成员函数声明为虚函数!

请看如下代码:

 class parentClass
{
public:
parentClass();
~parentClass(); void func_1(void);
virtual void func_2(void);
private:
}; class childClass : public parentClass
{
public:
childClass();
~childClass(); void func_1(void);
virtual void func_2(void);
private:
};

假如有以上声明,则在使用以上类时:

 childClass childTest;
parentClass *pParentTest = &childTest;
pParentTest->func_1();
pParentTest->func_2();

pParentTest指针类型是parentClass基类类型,但它指向的地址对象却是childClass的对象,这种情况下:func_1函数不是虚函数,则调用的是指针类型所在类的函数,即第三句执行的是基类中的func_1函数;func_2函数是虚函数,则调用的是指针指向对象的所在类的函数,即第四句执行的是子类中的func_2函数。

上面两段代码演示了虚函数最基本的使用,简单总结就是:基类中将某方法定义为虚函数,则在派生类中,该方法仍为虚方法。在使用时,定义基类类型的指针,使其指向派生类的对象,使用该指针调用某个方法,若该方法未被声明为虚函数,则调用的是指针类中的方法,若该方法是虚函数,则调用的是指针指向对象类中的该方法。这也即是动态联编。

其他情况:

1) 如上述4行代码,若有pParentTest->func_3();语句,其中func_3函数只在派生类中声明,基类中没有该方法,则会 编译报错 ;

2) 如上述4行代码,若有pParentTest->func_3();语句,其中func_3函数只在基类中声明,派生类中没有该方法,则会 调用基类的方法 ;

3) 如果基类声明被重载了,则应在派生类中重新定义所有的基类版本!如果派生类只重新定义了1个版本,则另外的版本将被隐藏,派生类对象无法调用;

4) 如果派生类要重新定义基类的方法,则派生类中的声明应与基类一致(函数名、参数、返回值),如果派生类的声明与基类参数不一致,则派生类的该方法将覆盖基类中的该方法(不构成重载),派生类对象只能按照派生类方法声明的格式进行调用!(基类中的该方法将被隐藏,派生类对象调用时会报错)

虚方法的一般使用条件:

1) 需要在派生类中重新定义基类的方法,则在基类中将该方法声明为虚方法;

2) 涉及到派生的,一般都将析构函数声明为虚函数;

3) 构造函数不能为虚函数!

4) 友元函数不能是虚函数,因为它不是类的成员函数!

C++虚方法(虚函数)随笔的更多相关文章

  1. C#语法-虚方法详解 Virtual 虚函数

    虚方法 / Virtual 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享. ...

  2. C#中的虚方法和抽象方法(Thirteenth Day)

    今天在云和学院学了很多,我这次只能先总结一下C#中的虚方法和抽象的运用. 理论: 虚方法: •用virtual修饰的方法叫做虚方法 •虚方法可以在子类中通过override关键字来重写 •常见的虚方法 ...

  3. JavaScript实现抽象类与虚方法(六)

    一:什么是js抽象类与虚方法 虚函数是类成员中的概念,是只做了一个声明而未实现的方法,具有虚函数的类就称之为抽象类,这些虚函数在派生类中才被实现.抽象类是不能实例化的,因为其中的虚函数并不是一个完整的 ...

  4. 关于C#中的抽象类、抽象方法和虚方法的探究

    2016年的第一篇文章,容我先喷喷新年的情怀,..........,好了,喷的差不多了. 在面向对象中,我们需要对类进行横向和纵向的认识,不同的类有不同特色的成员,同时在不同类的继承中,子类获得父类的 ...

  5. 为何JAVA虚函数(虚方法)会造成父类可以"访问"子类的假象?

      首先,来看一个简单的JAVA类,Base. 1 public class Base { 2 String str = "Base string"; 3 protected vo ...

  6. C# 工厂模式+虚方法(接口、抽象方法)实现多态

    面向对象语言的三大特征之一就是多态,听起来多态比较抽象,简而言之就是同一行为针对不同对象得到不同的结果,同一对象,在不同的环境下得到不同的状态. 实例说明: 业务需求:实现一个打开文件的控制台程序的d ...

  7. Delphi之静态方法,虚方法virtual,动态dynamic,抽象abstract,消息

    Delphi之静态方法,虚方法virtual,动态dynamic,抽象abstract,消息 http://www.cnblogs.com/zhwx/archive/2012/08/28/266055 ...

  8. 《转》 浅谈C# 多态的魅力(虚方法,抽象,接口实现)

    前言:我们都知道面向对象的三大特性:封装,继承,多态.封装和继承对于初学者而言比较好理解,但要理解多态,尤其是深入理解,初学者往往存在有很多困惑,为什么这样就可以?有时候感觉很不可思议,由此,面向对象 ...

  9. C#-面向对象的三大特性——多态(虚方法与重写、抽象类、接口)

    多态 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果.在运行时,可以通过指向基类的指针,来调用实现派生类中的方法. 编译时的多态性:编译时的多态性是通过重载来实现的.对于非虚的成员来说 ...

随机推荐

  1. 7 -- Spring的基本用法 -- 3...

    7.3 Spring 的核心机制 : 依赖注入 Spring 框架的核心功能有两个. Spring容器作为超级大工厂,负责创建.管理所有的Java对象,这些Java对象被称为Bean. Spring容 ...

  2. hibernate注解随笔—10月8日

    hibernate注解(herbinate4 jar包注解可用,使用hibernate3.3注解失败) 如果javabean与数据库中表名一致(不区分大小写),则注解不用写@Table(name=&q ...

  3. frame里的链接跳转

    <a href="javascript:parent.location='index_frame.html';void(0);">索引</a> <a ...

  4. android自动获取短信验证码

    前言:android应用的自动化测试必然会涉及到注册登录功能,而许多的注册登录或修改密码功能常常需要输入短信验证码,因此有必要能够自动获得下发的短信验证码.主要就是实时获取短信信息.android上获 ...

  5. Java—多线程编程

    一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程.一个线程不能独立的存 ...

  6. JavaScript 面向对象(二) —— 案例篇

    看案例前可以先看看基础篇:JavaScript 面向对象(一) —— 基础篇 案例——面向对象的选项卡:把面向过程的程序一步步改成面向对象的形式,使其能够更加的通用(但是通用的东西,一般会比较臃肿). ...

  7. win7/8/10安装过程中将动态磁盘转为basic

    在分区界面运行Shift+F10 在命令窗口运行Diskpart list diskpart select disk n(n为磁盘号) clean convert xxx PS:xxx代表要转换的结果 ...

  8. C# 技巧(3) C# 操作 JSON

    RestAPI中, 经常需要操作json字符串,  需要把json字符串"反序列化"成一个对象, 也需要把一个对象"序列化"成一字符串. C# 操作json, ...

  9. 设置apache登陆密码验证

    一.编辑虚拟目录配置文件,设置认证方式 Alias /test"/var/www/test"<Directory "/var/www/test">O ...

  10. WCF初探-25:WCF中使用XmlSerializer类

    前言 在上一篇WCF序列化和反序列化中,文章介绍了WCF序列化和反序列化的机制,虽然WCF针对序列化提供了默认的DataContractSerializer序列化引擎,但是WCF还支持其他的序列化引擎 ...