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指针)  




说明1:

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

说明2:

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

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






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值