C++ 虚拟函式的妙用 [大三TJB_708]

1 背景

        关于基类,派生类指标有以下结论:

  • 如果以一个基础类别之指标指向衍生类别之物件,那么该指标只能呼叫基础类所定义的函式。
  • 如果一个衍生类指标指向一个基础类别物件,必须先做明确的转型动作(对基础类之物件取地址&对派生类指标赋值)。这种做法很危险。
  • 如果基础类别和衍生类别都定义了相同名之成员函式,那么透过物件指标呼叫成员函式时,到底呼叫到哪一个函式,必须视该指标原始性别而定,而不是视指标实际所指之物件的性别而定

由于函式的呼叫是依赖指標的原始形态而不管它实际上指向物件(对象)。那么当指標的原始形态指向基础类(由基类定义指標),而此指標指向对象为衍生类定义对象,且我们需要用此指標访问跟基类同名的函数时,就可以依靠虚拟函式来实现这个功能。

在不同物件(由同一基类派生类定义的对象)中需要重新定义某个函数(一般内部代码会有所不同)时,即指向不同物件的指针调用同一函数时就会实现相应物件内重新定义函数的功能。这种性质就是多型,靠虚拟函式实现。

 

2 举一个不用虚拟函式的例子

#include <iostream.h>

ckass CShape
{
      public:
      void display(){cout << Shape \n";}
}
//----------------------------------------------
class CElipse : CShape
{
       public:
       void display(){cout << ""Elipse \n";}
}
//----------------------------------------------
class CCirlce : public CElipse
{
       void display(){ cout << ""Cirlce \n";}
}
现在main函数中编写以下代码
void main()
{
        CShape    ashpe;
        CElipse   aelipse;
        CCirlce   acircle;

        CShape *pShape;

        //--------ashpe-------
        pShape = &ashpe;
        pShape->display();

        //--------elipse------
        pShape = &aelipse;
        pShape->display();

        //---------circle--------
        pShape = &acircle;
        pShape->display();
}
则以上程序的输出结果为:
Shape
Shape
Shape
据程序运行结果,指向每个物件(Shape, elipse, circle)的函数都是调用类CShape中的函数,调用原理已经在this指標( http://blog.csdn.net/misskissc/article/details/8542411)中记载。
 

3 使用虚拟函式

在程序设计时,我们往往有这样的需求:每个物件都需要展现,但是展现的内容却有不同。就像aelipse和acircle需要展现自身的特点(elipse,circle),但是展现内容却不一样,但他们都同时想具有展现这个方法,只是需要在自己的类中重新定义展现这个方法而已。我们用虚拟函式来实现。
我们在以上定义类时在display函数前都加上virtual关键字,使之变成:
ckass CShape
{
      public:
      virtual void display(){cout << Shape \n";}
}
//----------------------------------------------
class CElipse : CShape
{
       public:
       virtual void display(){cout << ""Elipse \n";}
}
//----------------------------------------------
class CCirlce : public CElipse
{
       virtual void display(){ cout << ""Cirlce \n";}
}

然后main函数中的代码保持不变,则程序运行结果为:
Shape
Elipse
Circle
可见使用虚拟函式(形式为在相应函数面前加上virtual关键字)就能使派生类对应物件能够调用 自己(派生类)重新定义的函式。
 

4 虚拟函式使用

当希望定义衍生类别时重新定义某个函式时,在基类中把此函式添加定义为virtual类型
当用单一指令能带来不同功能是,称之为多型(main函数中的pShape->display语句)
虚拟函式是C++多型及动态连结的关键
虚拟函式衍生下去仍是虚拟函式,而且可以省略virtual关键字
 

5 后期连结与前期连结

以前面的pShape->display为例说明后期连结和前期连结
编译器无法在编译时期判断pShape->display是呼叫的哪个形式(使用虚拟函式与否),必须在执行时才能评估之,称为后期连结或动态连结;C函式和C++的非虚拟函式(non-virtual)在编译时期就转换为一个固定的呼叫地址的话,称为前期连结或者静态连结。

虚拟函式是C++多型及动态连结的关键

 

 

此次笔记记录完毕。


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、 1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READmE.文件(md如有),本项目仅用作交流学习参考,请切勿用于商业用途。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值