C++之封装继承和多态
C++中非常重要的概念,尤其是相对于C语言而言,也是其具有如此高的工程使用性的重要原因。
封装
所谓封装是将某些东西隐藏起来,让外界无法直接使用,而必须通过某些特定的方式才能访问。也即是,将抽象得到的数据和行为(类似于属性和方法)结合构成一个有机整体,将数据与操作数据的函数构成类,其中数据和函数都是类的成员。
其目的是将对象的使用者和设计者隔离开来,提高软件的可维护性和可修改性,使用者不必了解具体的实现细节而只是通过外部接口及特定的访问权限使用类成员,从而增强了安全性且简化了编程,也使得不同类之间的相互影响降到最低。
一个类的成员有三种访问权限可以选择
- public 所有人均可访问
- private 只有当前类中成员函数可以访问
- protected 只有当前类中和当前类的派生类中的成员函数可以访问
如果没有显示声明,class中的成员数据或成员函数默认访问权限是private,struct中默认访问权限是public
继承
指的是新类从已有的类中得到已有的特性。
继承使得子类具有父类的某些数据和函数,而不需要再次编写相同的代码,在继承的同时,子类也可以重新定义某些数据和函数并覆盖父类原有的数据和函数。
与类的成员访问权限相关,继承方式也分为三种:public,private,protected
一般分为单一继承和多重继承,常用的是单一继承,编程简单,可读性好。
需要注意的是class默认是private继承,而struct默认是public继承。
父类中的访问权限 | 继承方式 | 子类中的访问权限 |
public | public | public |
private | No access | |
protected | protected | |
public | private | private |
private | No access | |
protected | private | |
public | protected | protected |
private | No access | |
protected | protected |
子类会继承父类/基类除构造函数和析构函数以外的成员函数,一般析构函数定义为虚函数,否则的话析构时只会调用父类/基类中定义的析构函数而不会调用子类/派生类中的析构函数。
多态
父类成员函数前加virtual修饰就变成了虚函数。
纯虚函数就是父类只定义了虚函数而没有实现,则必须在子类中实现。如果子类中没有实现则子类仍为虚类,需要子类的子类去实现纯虚函数,即哪一层子类实现了纯虚函数,哪一层的子类才可以被初始化。纯虚函数相当于一个接口,子类必须实现这个接口才可以使用。
而多态性就是为了接口重用,无论传递过来的是哪个子类的对象,都能调用相应的子类函数。
多态是我们可以用相同的方式处理不同类型的对象,极大地提高了代码的可重复性。
多态性允许将子类类型的指针赋值给父类类型的指针,常通过虚函数来实现。虚函数就是允许子类重新定义的成员函数。
子类重写父类中的虚函数时,即使不用virtual声明,该函数也是虚函数,而父类中必须要有virtual声明。
一个接口,多种方法,多态主要有两种形式。
静态多态
在编译期将函数链接起来,此时即可确定调用哪个函数或模板,静态多态通过重载和模板实现。
在宏多态中,通过定义变量,编译时直接把变量替换,实现宏多态。
- 优点
- 泛型编程,STL,非常便利
- 编译期完成,提高了运行效率
- 具有很强的适配性和松耦合性
- 缺点
- 使得编程可读性降低,代码调试困难
- 无法实现木板的分离编译,工程量大时编译时间较长
- 无法处理异质对象集合
动态多态
在程序运行期间才能确定调用哪个函数或实现。父类指针或引用能够指向子类对象,调用子类的函数,所以在编译时无法确定调用哪个函数。
例如在父类中写一个虚函数,子类中进行重写,用一个指向父类的指针调用虚函数,实际上会调用在子类中重写的虚函数。
运行期多态的实现依赖于虚函数机制,当某个类声明了虚函数时,编译器将为该类对象安插一个虚函数表指针,并为该类设置一个唯一的虚函数表,表中存放该类虚函数的入口地址,运行期间通过虚函数表指针与虚函数表去确定该类虚函数的真正实现。
- 优点
- 面向对象设计中非常重要的特性,对客观世界直觉的认识。
- 可以处理同一继承体系下的异质类集合
vector<Animal*> anims;
Animal *anim1 = new Dog;
Animal *anim2 = new Cat; // 处理异质类集合实例
anims.push_back(anim1);
anims.push_back(anim2);
- 缺点
- 运行期间进行虚函数绑定,增加了程序运行开销
- 庞大的类继承层次,对接口的修改容易影响类的继承层次
- 虚函数在运行期绑定,编译器无法对其进行优化
C++之封装继承和多态的更多相关文章
- day33 序列类型,绑定方法,类方法,静态方法,封装继承和多态
Python之路,Day20 = 序列类型,绑定方法,类方法,静态方法,封装继承和多态 序列是指有序的队列,重点在"有序". 一.Python中序列的分类 Python中的序列主要 ...
- objective-c自学总结(三)---面向对象的封装,继承与多态
面向对象的三大特性 封装 继承 多态 1.封装: 隐藏属性,方法或实现细节的过程称为封装 信息隐藏,隐藏对象的实现细节,不允许用户看到 将东西包装在一 然后以新的完整形式呈现出来 例如,两种或多种化学 ...
- python 面向对象及封装继承和多态
######装饰器######装饰器的概念 - 装饰器的实现是函数里面嵌套函数;- 装饰器的本质是一个函数, 它可以让其他函数在不需要做任何代码改动的前提下增加额外的功能;- 装饰器需要传递一个函数, ...
- Java的封装继承和多态
封装 定义:属性私有private:get/set 目的 提高程序的安全性,保护数据 隐藏代码的实现细节 统一接口 提高系统的可维护性 代码 public class Student { //名字 p ...
- java封装继承以及多态(含代码)
封装 该露的露,该藏的藏 我们常需设计要追求,"高内聚,低耦合".高内聚就是类的内部数据操作细节自己完成.不允许外部干涉:低耦合:仅暴漏少量的方法给外部使用. 封装(数据的隐藏) ...
- C++学习笔记 封装 继承 多态 重写 重载 重定义
C++ 三大特性 封装,继承,多态 封装 定义:封装就是将抽象得到的数据和行为相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成类,其中数据和函数都是类的成员,目的在于将对 ...
- OC的封装、继承与多态
面向对象有三大特征:封装.继承和多态. 一.封装 封装是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问.简而言之,信息隐藏,隐 ...
- 2、C#面向对象:封装、继承、多态、String、集合、文件(上)
面向对象封装 一.面向对象概念 面向过程:面向的是完成一件事情的过程,强调的是完成这件事情的动作. 面向对象:找个对象帮你完成这件事情. 二.面向对象封装 把方法进行封装,隐藏实现细节,外部直接调用. ...
- java面向对象(封装-继承-多态)
框架图 理解面向对象 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程强调的是功能行为 面向对象将功能封装进对象,强调具备了功能的对象. 面向对象是基于面向过程的. 面向对象的特点 ...
随机推荐
- 【Web技术】353- CDN 科普
点击上方"前端自习课"关注,学习起来~ 一.概述 1.1 含义 CDN 的全称是 Content Delivery Network,即内容分发网络.CDN 是构建在网络之上的内容分 ...
- 关于 Kafka 的一些面试题目
上周客串了一下面试官,在这里就简单记录一下期间我问到的一些关于 Kafka 的面试题目,这些都是我平时在学习 Kafka 的一些总结要点. 谈谈你对 kafka 的整体认识? 问这个问题主要是想知道面 ...
- webpack 环境搭建
Webpack环境搭建 一.安装node 1.node官网下载node并安装----node里面内置了npm所以用在安装npm了 2.命令行输入node -v查看node是否安装成功 二.全局安装we ...
- 在MySQL中group by 是什么意思
mysql语法中group by是什么意思? 在百度中搜索半天,最后找到一篇解释比较好的(不是博文,是百度知道,很郁闷那么多网友怎么就没人解释的清楚),链接如下: http://zhidao.baid ...
- minicom配置1500000波特率
背景 项目需求,得用1500000波特率进行,即1.5M的波特率进行串口通信. 最开始以为minicom不支持,因为第一眼在配置界面的选项中没看见.后来发现其实是支持的 方式一 启动时带参数 -b 1 ...
- 准确率、精确率、召回率、F-Measure、ROC、AUC
先理解一下正类(Positive)和负类(Negetive),比如现在要预测用户是否点击了某个广告链接,点击了才是我们要的结果,这时,点击了则表示为正类,没点击则表示为负类. TP(True Posi ...
- oracle创建索引
数据库索引是为了提高查询速度的一种数据结构. 索引的创建语句 索引的创建语句非常简单. CREATE INDEX 索引名 ON 表名(列名); 除了单列索引,还可以创建包含多个列的复合索引. CREA ...
- javaWeb实现验证码--代码超简单
1.前端显示 HTML: <h3>验证码:</h3> <input type="text" name="validationCode&quo ...
- Linux修改History历史命令数量
****打开 vim /etc/profile vim /etc/profile 追加配置 # /etc/profile: system-wide .profile file for the B ...
- 三种页面置换算法的C++模拟
#include<iostream> using namespace std; ,,,,,,,,,,,,,,,,,,,,- }; void FIFO(); void OPT(); void ...