仅作个人笔记学习交流使用
进击的C++(一)
进击的C++(二)
进击的C++(三)
进击的C++(四)
进击的C++(五)
面向对象程序最关键的地方在于必须能够表现三大特性:封装,继承,多态!
封装指的是类中的敏感数据在外界是不能访问的;
继承指的是可以对已经存在的类进行代码复用,并使得类之间存在父子关系;
多态指的是相同的调用语句可以产生不同的调用结果。
一、C++对象模型
class是特殊的struct——
- 在内存中class依旧可以看做变量的集合
- class和struct遵循相同的内存对齐规则
- class中的成员函数与成员变量分开存放
每个对象有独立的成员变量
所有对象共享类中的成员函数
运行时对象退化为结构体的形式——
- 所有成员变量在内存中依次排布
- 成员变量之间可能存在内存空隙
- 可以通过内存地址直接访问成员变量
- 访问权限关键字在运行时失效
对象调用成员函数——
- 类中的成员函数位于代码段中
- 成员函数通过对象地址访问成员变量
- 调用成员函数时对象地址作为参数隐式传递(this指针)
- C++语法规则隐藏了对象地址的传递过程
继承对象模型——
子类是由父类成员叠加子类新成员得到的
二、多态对象模型
c++多态的实现原理——
- 当类中声明虚函数时,编译器会在类中生成一个虚函数表
- 虚函数表是一个存储成员函数地址的数据结构
- 虚函数表由编译器自动生成和维护
- virtual成员函数被编译器放入虚函数表中
- 存在虚函数时,每个对象都有一个指向虚函数表的指针
编译器检查成员函数是否为虚函数,若是则在对象VPTR指向的虚函数表中查找函数,若否则直接确定函数的地址,因此虚函数的调用效率低于普通成员函数。
三、抽象类和接口
抽象类
- 表现现实世界中的抽象概念
- 相关函数没有完整的实现
- 只能定义类型,而不能产生对象的类
- 只能被继承并重新相关函数
C++本身没有抽象类的概念,而是通过纯虚函数实现抽象类,纯虚函数指只定义原型的成员函数,=0 用于告诉编译器声明纯虚函数,不需要定义函数体。
class class_name
{
public:
virtual int fun()=0;
}
- 抽象类只能用作父类被继承
- 子类必须实现纯虚函数的具体功能
- 纯虚函数被实现后成为虚函数
- 如果子类没有实现纯虚函数,则子类成为抽象类
接口
- 类中没有定义任何的成员变量
- 所有的成员函数都是公有的(public)
- 所有的成员函数都是纯虚函数
- 接口是特殊的抽象类