欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

C++复习要点总结之十——多态(一)

程序员文章站 2024-01-25 08:14:46
...
多态的理解:

是一个面向对象新需求:

根据实际的对象类型来判断重写函数的调用

如果父类指针指向的是父类对象则调用父类中定义的函数

如果父类指针指向的是子类对象则调用子类中定义的重写函数

C++复习要点总结之十——多态(一)

解决方案:

Ø C++中通过virtual关键字对多态进行支持

Ø 使用virtual声明的函数被重写后即可展现多态特性

//面向对象3大概念

封装

突破了C语言函数的概念。。

继承

代码复用 。。。。我复用原来写好的代码。。。

多态

多态可以使用未来。。。。。80年代写了一个框架。。。。。。90年代人写的代码

多态是我们软件行业追寻的一个目标。。。

//写了一个框架,可以调用后来人,写的代码的能力

进一步的理解

//间接赋值成立的3个条件:

//1 定义两个变量。。。

//2 建立关联 。。。。

//3 *p

//多态成立的三个条件:

//1 要有继承

//2 要有函数重写。。。C 虚函数

//3 要有父类指针(父类引用)指向子类对象

//多态是设计模式的基础,多态是框架的基础

知识点1 虚析构函数

析构函数是为了释放资源,

当释放资源时有需求不能直接对对象释放时如:

C *myC = new C; //C继承B,B继承A类

delete myC; //直接通过子类对象释放资源 这种情况不需要写virtual 关键字

需要通过父类指针将所有的子类都对象的析构函数都执行一遍

想通过父类指针 释放所有的子类资源 (需要在最终父类的析构函数中加上virtual关键字)

void howtodelete(A *base)
{
delete base; //这句话不会表现成多态 这种属性
}

知识点2:重载和重写区别

函数重载

必须在同一个类中进行

子类无法重载父类的函数,父类同名函数将被名称覆盖(例如:父类中有函数a(),子类中也有函数a(),但是还有函数a(int b)这个函数就是重载父类函数产生错误!不能出现!)

重载是在编译期间根据参数类型和个数决定函数调用

函数重写

必须发生于父类与子类之间

并且父类与子类中的函数必须有完全相同的原型

使用virtual声明之后能够产生多态(如果不使用virtual,那叫重定义)

多态是在运行期间根据具体对象的类型决定函数调用

例子分析:

//1 C++编译器 看到func名字 ,因子类中func名字已经存在了(名称覆盖).所以c++编译器不会去找父类的4个参数的func函数
//2 c++编译器只会在子类中,查找func函数,找到了两个func,一个是2个参数的,一个是3个参数的.
//3 C++编译器开始报错..... error C2661: “Child::func”: 没有重载函数接受 4 个参数
//4 若想调用父类的func,只能加上父类的域名..这样去调用..
c1.func(1, 3, 4, 5);
//c1.func();
//func函数的名字,在子类中发生了名称覆盖;子类的函数的名字,占用了父类的函数的名字的位置
//因为子类中已经有了func名字的重载形式。。。。
//编译器开始在子类中找func函数。。。。但是没有0个参数的func函数

3 重点:

C++中多态的实现原理

当类中声明虚函数时,编译器会在类中生成一个虚函数表

虚函数表是一个存储类成员函数指针的数据结构

虚函数表是由编译器自动生成与维护的

virtual成员函数会被编译器放入虚函数表中

存在虚函数时,每个对象中都有一个指向虚函数表的指针(vptr指针)

C++复习要点总结之十——多态(一)

C++复习要点总结之十——多态(一)

C++复习要点总结之十——多态(一)

说明1:

通过虚函数表指针VPTR调用重写函数是在程序运行时进行的,因此需要通过寻址操作才能确定真正应该调用的函数。而普通成员函数是在编译时就确定了调用的函数。在效率上,虚函数的效率要低很多。

说明2:

出于效率考虑,没有必要将所有成员函数都声明为虚函数

说明3 :C++编译器,执行HowToPrint函数,不需要区分是子类对象还是父类对象

C++复习要点总结之十——多态(一)

以上就是C++复习要点总结之十——多态(一)的内容,更多相关内容请关注PHP中文网(www.php.cn)!

相关标签: C++,多态