1、面对对象1. 类和对象的关系2. 构造 函数3. 析构函数4. 内联函数5. static 成员6. const 成员7. 友元函数8. 运算符重载9. 继承性10. 多态性11. 异常处理1.类和对象关系类似于建筑图纸和大楼的关系,对象是类的一个实例。类中包括数据和函数,规定有哪些数据成员,哪些成员函数及具体功能。对象是类的实现,对象根据类的描述信息生成一个真实的事物,占实际内存,对象生成时要调用类的构造函数进行初始化,对象释放时要调用类的析构函数清理内存。类是一种用户自定义的数据类型(类似int) , 在定义时不分配任何内存。1.main 里定义对象(类名 变量) 2.调用成员函数时 (变
2、量.成员函数)1.封装将数据和函数封装到类中面对对象的特性 2.继承能被另一个类重用3.多态同一成员函数在不同类中有不同功能1.公有(public)类外任意访问类成员访问控制 2.保护(protected )类中或派生类中访问3.私有(private)本类访问(默认)2.构造函数对类中的成员变量进行集中初始化。先根据类的大小得到内存,用于存放类对象,再根据构造函数传入的参数和具体实现完成类对象的初始化。构造函数和类名相同(如果没有定义会自动生成一个无参的构造函数,完成内存的分配) 。构造函数没有返回值,可以重载多个构造函数。使用不同的参数列表,创建类对象时根据参数数目和类型自动匹配构造函数。R
3、ect(int leftTop,int rightBottom)x1=leftTop0; y1=leftTop1;x2=rightBottom0; y2=rightBottom1;Rect(int _x1,int _y1,int width,int height)x1=_x1; y1=_y1;x2=_x1+width; y2=_y1+height;在 main()里初始化给予一个初始值(例:Rect (10 20 15 15) )调 用 拷 贝 构 造 函 数 的 情 形在 C+中 , 下 面 三 种 对 象 需 要 调 用 拷 贝 构 造 函 数 ( 有 时 也 称 “复 制 构造 函 数
4、”) : 1) 一 个 对 象 作 为 函 数 参 数 , 以 值 传 递 的 方 式 传 入 函 数 体 ; 2) 一 个 对 象 作 为 函 数 返 回 值 , 以 值 传 递 的 方 式 从 函 数 返 回 ; 3) 一 个 对 象 用 于 给 另 外 一 个 对 象 进 行 初 始 化 ( 常 称 为 复 制 初 始 化 ) ;class CExample public: CExample()pBuffer=NULL; nSize=0; CExample()delete pBuffer; void Init(int n) pBuffer=new charn; nSize=n; priv
5、ate: char *pBuffer; /类 的 对 象 中 包 含 指 针 ,指 向 动 态 分 配 的 内 存 资 源 int nSize; ; 这 个 类 的 主 要 特 点 是 包 含 指 向 其 他 资 源 的 指 针 , pBuffer 指 向 堆中 动 态 分 配 的 一 段 内 存 空 间 。拷 贝 构 造 函 数 的 格 式 为 : 类 名 ( const 类 名 /拷 贝 构 造 函 数 的原 型 , 参 数 是 常 量 对 象 的 引 用 。 由 于 拷 贝 构 造 函 数 的 目 的 是 成 员 复 制 , 不 应修 改 原 对 象 , 所 以 建 议 使 用 cons
6、t 关 键 字 。 提 供 了 拷 贝 构 造 函 数 后 的 CExample 类 定 义 为 : class CExample public: CExample()pBuffer=NULL; nSize=0; CExample()delete pBuffer; CExample(const CExample /拷 贝 构 造 函 数 void Init(int n) pBuffer=new charn; nSize=n; private: char *pBuffer; /类 的 对 象 中 包 含 指 针 ,指 向 动 态 分 配 的 内 存 资 源 int nSize; ; CExamp
7、le:CExample(const CExample /复 制 常 规 成 员 pBuffer=new charnSize; /复 制 指 针 指 向 的 内 容 memcpy(pBuffer,RightSides.pBuffer,nSize*sizeof(char); 这 样 , 定 义 新 对 象 , 并 用 已 有 对 象 初 始 化 新 对 象 时 , CExample(const CExampleclass point public:point(int xx=0,int yy=0)X=xx,Y=yy; coutusing namespace std;class basepublic:
8、base()printf(“this is the base constructorn“);base()printf(“this is the base destructorn“);class derivative :public basepublic:derivative()printf(“this is the derivative constructorn“);derivative()printf(“this is the derivative destructorn“);int main(int argc, char* argv)derivative a;return 0;=运行结果:
9、this is the base constructorthis is the derivative constructor (派生类 构造函数)this is the derivative destructor (派生类 析构函数)this is the base destructor=结果分析:构造时,先构造基类再构造派生类析构时,先析构派生类,再析造基类。4.内联函数宏的加强版 定义一个宏-#define sum(a,b) 功能有限一个函数调用支出由调用开销和调用过程组成,所以内联函数适合代码短,调用频繁的函数。若成员函数的实现也在类中完成,默认为内联函数。inline 函数类型 函数名
10、(形参表)(在类中定义和实现的函数称为_内联函数_)5.Static 成员(静态成员变量)C 中C+类中静态成员不属于对象,是类的共享成员静态数据成员要在类外定义和初始化非静态成员函数也可以操作静态数据成员内联函数在编译时是将该函数的目标代码插入每个调用该函数的地方静态数据成员可以直接用类名调用下面是关于静态成员的说法,其中不正确的是(D ) 。A. 静态成员有类作用域,但与普通非静态成员有所不同B. 静态函数没有this指针,同一个类的不同对象拥有相同的静态数据成员C. 静态数据成员的初始化必须在类外进行D. 静态函数同样可以直接访问非静态数据成员this是 一 个 指 针 , 它 时 时
11、刻 刻 指 向 你 这 个 实 例 本 身使 用 : 一 种 情 况 就 是 , 在 类 的 非 静 态 成 员 函 数 中 返 回 类 对 象 本 身 的 时 候 , 直 接 使 用 return *this; 另 外 一 种 情 况 是 当 参 数 与 成 员 变 量 名 相 同 时 , 如 this-n = n ( 不 能写 成 n = n) 。#include using namespace std;class STA2public:int b;static int a;static int GetA()return a;int GetB()return this-b;int STA2
12、:a=20;int main()STA2 s1;s1.b=100;cout: ; 其 中 , 是 新 定 义 的 一 个 类 的 名 字 , 它 是 从 中 派 生 的 , 并 且按 指 定 的 派 生 的 。 常 使 用 如 下 三 种 关 键 字 给 予 表 示 : public 表 示 公 有 基 类 ; private 表 示 私 有 基 类 ; protected 表 示 保 护 基 类 ; 多 继 承 的 定 义 格 式 如 下 : class :, ; 可 见 , 多 继 承 与 单 继 承 的 区 别 从 定 义 格 式 上 看 , 主 要 是 多 继 承 的 基 类 多 于
13、一 个 。 如 果 省 略 继 承 方 式 , 对 class将 采 用 私 有 继 承 , 对 struct将 采 用 公 有 继 承 。 也 就 是 说 class Base1; struct Base2; class Derive:Base1,Base2; 那 么 , Derive 类 将 私 有 继 承 Base1,公 有 继 承 Base2。 相 当 于 : class Derive:private Base1,public Base2; 编 辑 本 段 派 生 类 的 三 种 继 承 方 式公 有 继 承 (public)、 私 有 继 承 (private)、 保 护 继 承 (
14、protected)是 常 用 的 三 种 继 承 方式 。 1. 公 有 继 承 (public) 公 有 继 承 的 特 点 是 基 类 的 公 有 成 员 和 保 护 成 员 作 为 派 生 类 的 成 员 时 , 它 们 都 保 持 原有 的 状 态 , 而 基 类 的 私 有 成 员 仍 然 是 私 有 的 , 不 能 被 这 个 派 生 类 的 子 类 所 访 问 。 2. 私 有 继 承 (private) 私 有 继 承 的 特 点 是 基 类 的 公 有 成 员 和 保 护 成 员 都 作 为 派 生 类 的 私 有 成 员 , 并 且 不 能被 这 个 派 生 类 的 子
15、类 所 访 问 。 3. 保 护 继 承 (protected) 保 护 继 承 的 特 点 是 基 类 的 所 有 公 有 成 员 和 保 护 成 员 都 成 为 派 生 类 的 保 护 成 员 , 并 且只 能 被 它 的 派 生 类 成 员 函 数 或 友 元 访 问 , 基 类 的 私 有 成 员 仍 然 是 私 有 的 。 下 面 列 出 三 种 不 同 的 继 承 方 式 的 基 类 特 性 和 派 生 类 特 性 。2、继承方式与访问控制属性1. 派 生 类 是 基 类 的 具 体 化类 的 层 次 通 常 反 映 了 客 观 世 界 中 某 种 真 实 的 模 型 。 在 这
16、种 情 况 下 , 不 难 看 出 : 基 类是 对 若 干 个 派 生 类 的 抽 象 , 而 派 生 类 是 基 类 的 具 体 化 。 基 类 抽 取 了 它 的 派 生 类 的 公 共 特征 , 而 派 生 类 通 过 增 加 行 为 将 抽 象 类 变 为 某 种 有 用 的 类 型 。 2. 派 生 类 是 基 类 定 义 的 延 续先 定 义 一 个 抽 象 基 类 , 该 基 类 中 有 些 操 作 并 未 实 现 。 然 后 定 义 非 抽 象 的 派 生 类 , 实现 抽 象 基 类 中 定 义 的 操 作 。 例 如 , 虚 函 数 就 属 此 类 情 况 。 这 时 ,
17、 派 生 类 是 抽 象 的 基 类 的实 现 , 即 可 看 成 是 基 类 定 义 的 延 续 。 这 也 是 派 生 类 的 一 种 常 用 方 法 。 3. 派 生 类 是 基 类 的 组 合在 多 继 承 时 , 一 个 派 生 类 有 多 于 一 个 的 基 类 , 这 时 派 生 类 将 是 所 有 基 类 行 为 的 组 合 。派 生 类 将 其 本 身 与 基 类 区 别 开 来 的 方 法 是 添 加 数 据 成 员 和 成 员 函 数 。 因 此 , 继 承 的机 制 将 使 得 在 创 建 新 类 时 , 只 需 说 明 新 类 与 已 有 类 的 区 别 , 从 而
18、大 量 原 有 的 程 序 代 码 都可 以 复 用 , 所 以 有 人 称 类 是 “可 复 用 的 软 件 构 件 ”。_公有派生_类的对象可作为_基_类的对象处理。10.多态性多态性和函数重定义的区别:重定义函数的调用与指针类型相关,编译时确定了调用的函数版本。多态函数的调用与指针实际所指对象相关,在程序运行时才确定调用。动态绑定:在基类中声明为虚函数,在派生类中对该函数重写(实现继承来的函数)若基类析构设为 virtual(虚函数) ,派生类的析构自动为virtual,所以建议将基类中的析构函数声明为 virtual,会全部一起析构。纯虚函数只有函数声明,没有具体实现。 (接口的规范)
19、包含纯虚函数的类称为抽象类,不能用于创建类对象,主要用于对类功能的描述,类似于接口,其派生类必须重写全部纯虚函数。Virtual void calc();虚函数Virtual void calc()=0;纯虚函数(无函数体)虚函数Virtual 函数类型 函数名(形参表) ;声明只能在类定义中的函数原型声明中,不能在成员函数实现的时候。虚函数使用对象指针来访问(绑定过程在运行中完成)Void fun( base *ptr)ptr-display();Mammal* pDog = new Dog;pDog-speak();delete pDog;基类虚函数如名称,参数(个数,类型) ,返回值相同
20、;则派生类自动确定为虚函数。运行多态 1.赋值兼容规则2.声明虚函数3.由成员函数来调用或通过指针,引用来访问虚函数动 态 联 编 又 称 动 态 关 联 定 义 : 编 译 程 序 在 编 译 阶 段 并 不 能 确 切 知 道 将 要 调 用 的 函 数 , 只 有 在 程 序 执 行时 才 能 确 定 将 要 调 用 的 函 数 , 为 此 要 确 切 知 道 该 调 用 的 函 数 , 要 求 联 编 工 作要 在 程 序 运 行 时 进 行 , 这 种 在 程 序 运 行 时 进 行 联 编 工 作 被 称 为 动 态 联 编 。 动 态 联 编 必 须 包 括 以 下 方 面 :
21、成 员 函 数 必 须 声 明 为 virtual 如 果 基 类 中 声 明 了 为 虚 函 数 , 则 派 生 类 中 不 必 再 声 明 。 调 用 方 式 : 通 过 对 象 的 指 针 或 引 用 调 用 成 员 函 数 ; 或 通 过 成 员 函 数 调 用 , 反 之 就 无法 实 现 动 态 联 编 。 例 如 : #include #include using namespace std; class CBuilding /定 义 建 筑 类 string name; /定 义 名 称 public: void set(string strName); /修 改 名 称 vi
22、rtual void display() /显 示 信 息 , 这 里 是 内 联 函 数 , 而 且 声 明 为虚 函 数 cout (60.40); /修 改 桥 的 长 度 bridge.display(); /显 示 桥 的 信 息 return; #include using namespace std;class Mammalpublic:Mammal()cout speak();delete pDog;return 0;11.异常处理异常(exception )正常执行的代码放入 try语句块中,catch块中放入处理异常的代码。若有异常。则停止执行 try 块中的剩余语句,直接跳入 catch 块中执行异常处理代码。try 和 catch 区分代码 (增强代码可读性)函数中的 throw 语句用于抛出异常,catch 语句捕获异常并处理 (类型一致才能捕获) 。