C++三大特性之多态简述

多态

一.概念:相同对象收到不同消息,或者,不同对象收到相同消息
二.静态多态(早绑定):在编译时,已确定使用哪个函数(eg:函数同名异参—函数重载)
三.动态多态(晚绑定):在运行时,才确定使用哪个函数

virtual关键字

一.不能使用virtual的函数
(1)全局函数:即普通函数,否则编译报错
(2)静态成员函数:与类共生存,而非对象,否则编译报错
(3)内联函数函数:inline失效
(4)构造函数:编译报错
二.virtual写法建议
(1)统一写在前面:

  virtual public Person;  //虚继承

  //在类的头文件中声明并定义
  virtual inline void test(){    }                     //不用分号

(2)即便默认有virtual,也要加上virtual(eg:待实现/已实现的纯虚函数)
(3)基类的析构函数均加上virtual,防止因构造函数中申请堆内存,而未在析构函数中释放,导致内存泄漏

虚函数表

一.指针例举分类
(1)指向对象入口地址:对象指针
(2)指向函数入口地址:函数指针
(3)指向虚函数表入口地址:虚函数表指针
二.虚函数表
(1)概念:每个类(除了空类,就是没有方法也没有属性的类)在创建的时候,就会生成一个虚函数表指针vftable_ptr,虚函数表中存着对象的虚函数指针
(2)说明:(该内存示意图片来自imooc)
这里写图片描述
Circle对象通过vftable_ptr找到虚函数表,经过偏移找到某个虚函数的指针

A.对象的大小:数据成员的大小+虚函数指针(32位4字节,64位8字节)
(若两者均不存在,则以1个字节标记对象的存在)
B.虚函数指针在对象内存中占第一个

Ps:指针++,每次走4个字节

(3)弊端:维持表,需要加大系统开销
(4)情况:
(若子类重写父类的方法,则关于该方法在各自虚函数中入口地址不一样,否则一样)

A.父类实现了非virtual修饰的方法一,子类继承父类,子类没有再实现方法一

B.父类实现了非virtual修饰的方法一,子类继承父类,子类重写了方法一:(即隐藏

父类指针指向子类对象的时候,调用方法一时会用父类虚函数表中方法一的入口
子类调用方法一时,使用的是子类虚函数表中的方法一的入口

C.父类实现了virtual修饰的方法一,子类继承父类,子类没有再实现方法一:同A

D.父类实现了virtual修饰的方法一,子类继承父类,子类重写了方法一:(即覆盖
在父类指针指向子类对象时,父类的虚函数表方法一的入口地址会被子类的覆盖,从而多态

纯虚函数

一.定义:没有方法体,且等于0的虚函数(在虚函数表中的指针值为0)
二.举例:
virtual double test()=0;
三.抽象类
(1)定义:含有纯虚函数的类
(2)特点:不能直接实例化,否则编译报错;
这里写图片描述
但子类实例化时,抽象类会被间接实例化

(3)子类:抽象类的子类实现所有的纯虚函数才不是抽象类
四.接口类
(1)概念:仅含有纯虚函数
(2)使用:
A.接口类只需.h文件
B.实现接口类的子类必须声明将所有的纯虚函数声明为虚函数

RTTI(运行时类型识别 Run-Time Type Idetification)

一.typeid:
(1)头文件:需添加#include,不然typeid无法使用,程序无法编译的
(2)适用:任何数据类型,包括对象,类(但只能获取对象的实际类型)
(3)示例:

typeid(int);
typeid(*obj).name();   //obj为指针
typeid(Bird);  //Brid为类

(4)返回:type_info对象的引用
(5)注意:要返回实际类型,则基类必须有虚函数,否则为定义时类型
二.dynamic_cast:
1.适用:
(1)某个类型指针和引用的转换,即不能是某个类型本身
(2)源转换类型必须包含虚函数,否则转换失败
(3)转换成功,返回子类对象的地址,否则NULL
2.示例:

dynamic_cast<Brid *>(obj);//obj 是指向基类的指针,不能直接操作子类的方法。

异常处理

一.引入:避免异常抛至操作系统,操作系统直接关闭程序,对用户不友好
二.过程:
这里写图片描述

三.基本思想:主逻辑和异常处理分开
四.用法:

fun(){
throw string(“exception”);
}
fun1(){
throw SizeErr();
}
(1)catch(类型):
Int main(){
try {
fun();
}
catch(string){
...
}
catch(...){ //捕获任何类型
...
}
return 0;
}
(2)catch(值):
int main(){
try {
fun();
}
catch(string &aval){
cout<<aval<<endl;
}
return 0;
}

五.常用异常:下标,除数为0,内存不足(死循环,或者内存泄漏)
六.多态:(Exception接口类) 下图来自imooc网
这里写图片描述

int main(){
try {
fun()1;
}
catch(Exception &e){
...
}
return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值