面向对象变成_C++_继承和多态

面向对象程序设计通过继承将有相似关系的类构成一种层次关系,实现代码的重用;通过多态,在一定程度上忽略相似类型的区别,用统一的方式使用他们的对象。


继承:继承体系中有基类、派生类。
基类中的函数分为两种:一种是基类希望其派生类进行覆盖的函数,即虚函数,一种是基类希望派生类直接继承而不要改变的函数。任何构造函数之外的非静态函数都可以是虚函数,如果基类将一个函数定义为虚函数,则其在派生类中也是虚函数。
派生类首先要通过类派生列表指明其基类,而且必须将继承而来的成员函数中需要覆盖的那些(即虚函数)重新声明(可以不加virtual)。
基类和派生类之间的类型转换是面向对象编程的关键所在。派生类中含有对应基类的组成部分,所以派生类可以向基类转换。需要注意的几点:
1、从派生类向基类的类型转换只对指针或引用有效。
2、基类向派生类不存在隐士类型转换。(但可以强制类型转换)
3、派生类向基类的转换也会由于访问控制变得不可行。
之所以只对指针和引用有效是因为只有指针和引用的静态类型和动态类型可能不一致,静态类型是编译时已知的,动态类型是内存中的对象类型,只在运行时才可知。一个对象可以进行哪些操作是有静态类型决定的!
其实不存在对象之间的类型转换,之所以可以直接进行对象间的初始化,赋值是因为调用了拷贝构造函数和重载的赋值运算符,他们的参数都是引用。


多态是面向对象变成的核心思想,具有继承关系的多个类型成为多态类型,我们使用这些类型的多种形式而无需在意他们的差异。
多态通过虚函数实现,引用和指针的静态类型和动态类型不一致是多态的基础。使用多态的一般过程是,定义基类的引用或指针,然后通过该引用或指针调用虚函数,实际调用的函数是由该引用或指针的动态类型决定的。
纯虚函数是虚函数后加=,包含纯虚函数的类是抽象基类,可以在类外提供纯虚函数的定义。抽象基类负责提供定义接口,派生类可以覆盖该接口,而且不能创建抽象基类的对象。


派生类的作用于在基类的作用域之内。C++函数调用p->mem()一般分为4步:
1、首先确定p的静态类型。
2、在p的静态类型对应的类中查找men函数。如果找不到,则依次在直接基类中不断查找直到继承链的顶端,仍未找到则编译器报错。
3、一旦找到mem,就进行常规类型检查。如果参数不匹配,则报错。
4、如果参数匹配,则根据调用的是否是虚函数产生不同的代码
   --如果mem是虚函数,且是通过引用或者指针调用的,则编译器产生的代码在运行时确定运行虚函数的版本。
   --如果men不是虚函数,或者是通过对象调用的,则编译器产生常规的函数调用。
遵循的原则还是名字查找先于类型检查。


因为派生类的作用域在基类的作用域之内,所以如果派生类内定义的函数会**隐藏**基类中同名的函数。如果覆盖(重写)虚函数时,不小心将参数写错,编译器不会报错。C++11添加了override关键字,这样编译器会在覆盖虚函数时进行类型检查。
除了覆盖继承而来的虚函数外(当然,也不一定全部覆盖),派生类最好不要重用定义在基类中的名字。


派生类的构造函数:派生类通过基类的构造函数初始化它的基类部分,除非特别指出,否则派生类对象的基类部分会像数据成员一样执行默认初始化。
每个类负责定义各自的接口。想要与类的对象交互必须使用该类的接口,即使这个对象是派生类的基类部分也是如此。
除了构造函数,拷贝构造函数,赋值运算符也是如此。

通常将基类的析构函数定义为虚函数,以保证当delete一个动态分配的对象的指针是执行正确版本的析构函数。
构造函数会先构造基类的数据成员,析构函数正好相反,会先析构派生类的数据成员。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值