C++ 重温

虚函数

定义

定义:在某 基类中声明为 virtual 并在一个或多个 派生类中被重新定 义的 成员函数
语法:virtual 函数返回类型 函数名(参数表) {  函数体 }
用途 实现 多态性,通过指向 派生类基类 指针,访问派生类中同名覆盖 成员函数
虚函数必须是基类的非 静态成员函数,其访问权限可以是private或protected或public,在基类的类定义中定义虚函数的一般形式:
class  基类名{
.......
virtual 返回值类型 将要在 派生类重载的函数名( 参数列表);
};

作用

虚函数的作用是实现 动态联编,也就是在程序的运行阶段动态地选择合适的 成员函数,在定义了虚函数后,可以在 基类派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的 形参个数和形参类型。以实现统一的接口,不同定义过程。如果在 派生类中没有对虚函数重新定义,则它继承其 基类的虚函数。
当程序发现虚函数名前的关键字virtual后,会自动将其作为 动态联编处理,即在程序运行时动态地选择合适的成员函数。虚函数是C++ 多态的一种表现。
例如:子类继承了父类的一个函数(方法),而我们把父类的 指针指向子类,则必须把父类的该函数(方法)设为virtual(虚函数)。
([2010.10.28] 注:下行语义容易使人产生理解上的偏差,实际效果应为:
如存在:Base -> Derive1 -> Derive2 及它们所拥有的虚函数func()
则在访问 派生类Derive1的实例时,使用其 基类Base及本身类型Derive1,或被 静态转换的后续派生类Derive2的 指针或引用,均可访问到Derive1所实现的func()。)
动态联编规定, 只能通过指向基类指针或基类对象的引用来调用虚函数,其格式:
1、指向 基类的指针变量名->虚函数名( 实参表)
2、 基类对象的引用名. 虚函数名( 实参表)
使用虚函数,我们可以灵活的进行 动态绑定,当然是以一定的开销为代价。如果父类的函数(方法)根本没有必要或者无法实现,完全要依赖子类去实现的话,可以把此函数(方法)设为virtual 函数名=0 我们把这样的函数(方法)称为 纯虚函数
如果一个类包含了 纯虚函数,称此类为 抽象类


函数覆盖

函数覆盖发生在父类与子类之间,其函数名、参数类型、返回值类型必须同父类中的相对应被覆盖的函数严格一致,覆盖函数和被覆盖函数只有 函数体不同,当派生类对象调用子类中该同名函数时会自动调用子类中的覆盖版本,而不是父类中的被覆盖函数版本,这种机制就叫做函数覆盖。
1。覆盖函数,即在子类中用相同的函数名和签名重写父类的方法,虚函数,在子类中用相同的函数名和签名重写父类的方法(前面有virtual关键字)。如下   
2。在将父类对象的 指针指向子类对象的时候   Father*   father   =   new   Child;   
如father->FunctionA(),则执行的是Father中的实现;father->FunctionB(),   
则执行的是Child中的实现。   
3。如果直接声明子类对象,Child   child;则无论child.FunctionA()还是           child.FunctionB(),执行的都是Child中的实现。   
总结:调用函数的时候,关键看对象的类型 。   
记住是对象的类型,不管是 指针还是引用(同样是对象的类型)。   
好了有了对象的类型就好办了。当你用这个对象(或者是 指针、引用)去调用函数时,   
1:该对象(实体)即不是 指针或引用的形式,可以轻松的调用函数。   
2:但是当我们用引用或 指针形式时,有个问题是区别指针(引用)的类型和指针(引用)所指实体对象的类型。
A:你用 指针来调用某函数,若函数是非 虚函数,非虚函数是 静态编译的(即编译时刻确定的)。也就是说他不会去 虚函数表找这个函数(因为不是虚函数),因 此调用的是 指针类型的那个类的相关函数。即使派生类有这个函数(这是实际编程时的大忌!!!)。这就是  你的void   FunctionA()   const   ;   
B:   当你用这个 指针去调用一个 虚函数时,他就到 虚函数表中,找这个名字的函数,从指针所指对象的类型(即派生类)依次向父类走,直到遇到第一个与次匹配的函数名。 

函数重载


所谓函数重载是指同一个函数名可以对应着多个函数的实现。每种实现对应着一个 函数体 ,这些函数的名字相同,但是函数的参数的类型不同。这就是函数重载的概念。函数重载在 类和对象 的应用尤其重要。

概述

函数重载要求 编译器能够唯一地确定调用一个函数时应执行哪个函数代码,即采用哪个函数实现。确定函数实现时,要求从函数参数的个数和类型上来区分。这就是说,进行函数重载时,要求同名函数在参数个数上不同,或者参数类型上不同。否则,将无法实现重载。例如,可以给函数名add()定义多个函数实现,该函数的功能是求和,即求两个 操作数的和。其中,一个函数实现是求两个int型数之和,另一个实现是求两个 浮点型数之和,再一个实现是求两个复数的和。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值