面向对象程序设计的的基本特点
抽象
是指对具体问题(对象)进行概括,抽出一类对象的公共性质并加以描述的过程
包括:数据抽象和行为抽象
封装
是将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的函数代码进行有机地结合,形成“类”,其中地数据和函数都是类的成员
继承
在一般概念基础上,派生出特殊概念,使得一般概念中得属性和行为可以被特殊概念共享,摆脱重复分析、重复开发的困境
多态
是指一段程序能够处理多种类型对象的能力
C++语言中4种形式
- 强制多态
- 重载多态
- 类型参数化多态
- 包含多态
类和对象
在面向对象程序设计中,程序模块是由类构成的
类是对逻辑上相关的函数与数据的封装,它是对问题的抽象描述
类成员的访问机制
类的长远包括数据成员和函数成员
3种访问控制属性
- public
- private
- protected
公有类型成员定义了类的外部接口
私有成员只能被本类的成员函数访问,来自类外部的任何访问都是非法的
保护类型成员的性质和私有数据成员的性质相似,其差别在于继承过程中对产生的新类影响不同
对象
声明一个对象 类名 对象名;
访问对象的数据成员 对象名.数据成员名
调用对象的函数成员 对象名.函数成员名(参数表)
类的成员函数
成员函数的实现
- 函数的原型声明写在类体种
- 函数的具体实现写在类定义外
成员函数调用中的目的对象
“.”操作符
在类的成员函数中,既可以访问目的对象的私有成员,又可以访问当前类的其他对象的私有成员
带默认形参值的成员函数
类成员函数的默认值,一定要写在类定义中,而不能写在类定义之外的函数中
内联成员函数
两种声明方式
- 隐式声明 将函数体直接放在类体内
- 显式声明 采用关键字inline显式声明,在函数体实现时,在函数返回值类型前加上inline;类定义中不加入该函数体
构造函数和析构函数
在定义对象的时候进行的数据成员设置,称为对象的初始化
构造函数
对象建立过程
- 在程序执行过程中,当遇到对象定义时,程序会向操作系统申请一定的内存空间用于存放新建的对象
- 与普通变量相比,类的对象太复杂了,编译器不知道如何产生代码来实现初始化
- 因此,如果需要进行对象初始化,程序员要编写初始化程序
构造函数的作用:就是在对象被创建时利用特定的值构造对象,将对象初始化为一个特定的状态
构造函数也是类的一个成员函数
除具有一般成员函数的特征外,还有一些特殊的性质
- 构造函数的函数名与类名相同,而且没有返回值
- 构造函数通常被声明为公有函数
构造函数在对象被创建的时候被自动调用
- 只要类中有了构造函数,编译器就会在建立新对象的地方自动插入对构造函数的调用代码
默认构造函数
- 调用时无须提供参数的构造函数
- 如果类中没有写构造函数,编译器会自动生成一个隐含的默认构造函数,该构造函数的参数列表和函数体皆为空
- 如果类中声明了构造函数,编译器便不会再为之生成隐含的构造函数
通常要定义自己的默认构造函数
- 由于编译器只在类不包含任何构造函数的情况下才会替我们生成默认构造函数,一旦我们定义了其他的构造函数,那么除非我们自己再定义一个默认的构造函数,否则构造类将没有默认构造函数
- 合成的默认构造函数可能会执行错误的操作
- 有时候编译器不能为某些类合成默认构造函数
委托构造函数
- 使用它所属类的其他构造函数执行它自己的初始化过程
- 它把滋生的一些(或全部)职责委托给了其他构造函数
当一个构造函数委托给另一个构造函数时,受委托的构造函数的初始值列表和函数体一次执行,然后控制权才会交还给委托函数
复制构造函数
- 它的形参是本类的对象的引用
- 作用是使用一个已经存在的对象(由复制构造函数的参数指定),去初始化同类的一个新对象
- 实现同类对象之间数据成员的传递
隐含的复制构造函数
- 没有定义复制构造函数,系统就会再必要时自动生成一个隐含的复制构造函数
- 功能是:把初始值对象的每个数据成员的值都复制到新建立的对象中
复制构造函数声明 类名(类名 &对象名);
复制构造函数的实现 类名::类名(类名 &对象名){ 函数体 }
复制构造函数在3种情况下都会被调用
- 用类中的一个对象去初始化该类的另一个对象时
- 如果函数的形参是类的对象,调用函数时,进行形参和实参结合时
- 如果函数的返回值是类的对象,函数执行完成返回调用者时
析构函数
用来完成对象被删除前的一些清理工作
是在对象的生存期即将结束的时刻被自动调用的
析构函数不接受任何参数,但可以是虚函数
移动构造函数
右值引用,表明被引用对象在使用后会被销毁,不会再继续使用
左值
- 位于赋值语句左侧的对象变量
- 对持久存在变量的引用,称之为左值引用
右值
- 赋值语句右侧的值,不依附于对象
- 对短暂存在可被移动的右值的引用称之为右值引用
通过移动右值引用对象来安全地构造新对象,并且避免冗余复制对象的代价
move函数
将左值对象移动成右值
移动构造函数
- 参数为该类对象的右值引用
- 在构造中移动源对象资源
- 构造后源对象不再指向被移动的资源
- 源对象可重新赋值或被销毁
default、delete函数
=default可显示要求编译器自动生成默认或复制构造函数
当用户不希望定义的类存在复制时,都可以通过delete关键字将复制构造函数删除
类的组合
描述的就是一个类内嵌其他类的对象作为成员的情况,它们之间的关系是一种包含与被包含的关系
- 当创建类的对象时,如果这个类具有内嵌对象成员,那么各个内嵌对象将被自动创建
- 在创建对象时既要对本类的基本类型数据成员进行初始化,又要对内嵌对象成员进行初始化
组合类构造函数定义的一般形式:
类名::类名(形参表):内嵌对象1(形参表),内嵌对象2(形参表),...
{类的初始化}
构造函数的调用顺序:
- 调用内嵌对象的构造函数,调用顺序按照内嵌对象在组合类的定义种出现的次序
- 执行本类构造函数的函数体
两类数据成员的初始化,必须在构造函数的初始化列表中进行
- 那些没有默认构造函数的内嵌对象
- 引用类型的数据成员——因为引用型变量必须在初始化时绑定引用的对象
析构函数的调用执行顺序与构造函数刚好相反
- 析构函数的函数体被执行完毕后,内嵌对象的析构函数被一一执行
- 这些内嵌对象的析构函数调用顺序与它们在组合类的定义种出现的次序刚好相反
前向引用声明