网络游戏开发语言基础 ——c++ 程序设计
DESCRIPTION
第八章 继承与多态. 网络游戏开发语言基础 ——C++ 程序设计. 第八章 继承与多态. 静态多态的实现 动态多态的实现 纯虚函数与抽象基类. 静态多态的实现 动态多态的实现. 动态多态的实现. 掌握静态多态的实现 掌握动态多态的实现 熟悉纯虚函数与抽象基类的应用. 第八章 继承与多态. 8.2 多态性 8.2.1 多态的含义,实现意义及分类. 多态的含义. 多态( polymorphism )一词最初来源于希腊语 polumorphos ,含义是具有多种形式或形态的现象。 - PowerPoint PPT PresentationTRANSCRIPT
专业教程理论讲解部分
网络游戏开发语言基础—— C++ 程序设计
第八章 继承与多态
第八章 继承与多态
静态多态的实现动态多态的实现纯虚函数与抽象基类
静态多态的实现动态多态的实现动态多态的实现
掌握静态多态的实现 掌握动态多态的实现熟悉纯虚函数与抽象基类的应用
• 8.2 多态性• 8.2.1 多态的含义,实现意义及分类
第八章 继承与多态
多态( polymorphism )一词最初来源于希腊语 polumorphos ,含义是具有多种形式或形态的现象。
在程序设计领域,一个广泛认可的定义是“一种将不同的特殊行为和单个泛化记号相关联的能力”,这里的泛化记号其实指的就是函数名。
• 多态的含义
• 8.2 多态性• 8.2.1 多态的含义,实现意义及分类
第八章 继承与多态
C++ 程序中允许大量的同名函数出现,体现出多态的使用价值。
• 多态的意义
1 )对不同的数据类型,采用相同或是相似的操作时,使用同名函数。2 )在程序运行中,在某个环节要调用对象的一个特定的方法,而不管这个
对象是由哪一个类创建的,这些类都支持这种方法。
• 8.2 多态性• 8.2.1 多态的含义,实现意义及分类
第八章 继承与多态
C++ 程序中,按照实现机制,多态可以分为两种
• 多态的类型
C++ 语言允许函数重载和运算符重载,使用同样的函数名和同样的运算符来完成不同的数据处理与操作。
C++ 语言程序中允许存在有若干函数,有完全相同的函数原型,却可以有多种多样的相异的函数体。
overloading overriding
• 8.2 多态性• 8.2.2 静态多态的实现方法
第八章 继承与多态
函数重载指的是,允许多个不同函数使用同一个函数名,但要求这些同名函数具有不同的参数表(当然,函数体的实现代码通常也不同)。
系统对这种多态性,对同名函数的处理比较简单。在编译过程中就可以确定该函数与程序中的哪一段代码相联系,即在编译时就已确定函数调用语句对应的函数体代码,故称为静态联编( static banding )处理方式。
• 8.2 多态性• 8.2.2 静态多态的实现方法
第八章 继承与多态
• 示例
void run(int a);void run(float a);run(1);run(1.0);
• 8.2 多态性• 8.2.2 动态多态的实现方法
第八章 继承与多态
C++ 语言程序中允许存在有若干函数,有完全相同的函数原型,却可以有多种多样的相异的函数体,这种现象称为函数的覆盖。
在编译阶段,系统是无法判断此次调用应执行哪一段函数代码。只有到了运行过程中执行到此处时,才能临时判断应执行哪一段函数代码,这种处理方式称为动态联编( dynamic banding )。
• 8.2 多态性• 8.2.2 动态多态的实现方法
• 1. 虚函数
第八章 继承与多态
虚函数是 C++ 语言中的重要概念。虚函数在编程中的灵活使用,可使程序具有更好的结构和可重用性。
virtual 返回类型 函数名 ( 参数表 ) {…… };
• 示例
virtual void run(int a){
…… } ;
• 8.2 多态性• 8.2.2 动态多态的实现方法
• 1. 虚函数
第八章 继承与多态
虚函数常用于基类与派生类中class graphelem { //自定义类 graphelem,将作为其它图元类的基类protected:int color; //颜色 colorpublic:graphelem(int col){color=col;}virtual void draw(){ …… };//基类中含有一个虚函数virtual ~graphelem() { …… };};
• 基类
• 8.2 多态性• 8.2.2 动态多态的实现方法
• 1. 虚函数
第八章 继承与多态
虚函数常用于基类与派生类中class line:public graphelem{ //自定义类 line,为基类 graphelem 的派生类public:virtual void draw(){ …… }; //虚函数 draw “,负责画出 line”...};class circle:public graphelem{ //自定义类 circle,为基类 graphelem 的派生类public:virtual void draw(){ …… }; //虚函数 draw “,负责画 circle”……} ;
• 派生类
• 8.2 多态性• 8.2.2 动态多态的实现方法
• 1. 虚函数
第八章 继承与多态
使用虚函数时,需要注意以下 3 点说明某一函数成员为虚函数,方法是在说明前加关键字“ virtual” 。
派生类中虚函数处的关键字 virtual 可以省略,但基类处的不可省
调用虚函数时,系统对它将采用动态联编的方式进行处理。
• 8.2 多态性• 8.2.2 动态多态的实现方法
• 2. 动态联编的机制
第八章 继承与多态
使用动态联编时,确定要调用的函数有两种方式
line ln1; circle cir1; triangle tri1;ln1.draw(); cir1.draw(); tri1.draw();
• 通过类对象
• 8.2 多态性• 8.2.2 动态多态的实现方法
• 2. 动态联编的机制
第八章 继承与多态
使用动态联编时,确定要调用的函数有两种方式
graphelem *pObj;line ln1; circle cir1; triangle tri1;pObj=&lin1; pObj->draw();pObj=&cir1; pObj->draw();pObj=&tri1; pObj->draw();
• 通过指针
• 8.2 多态性• 8.2.2 动态多态的实现方法
• 2. 动态联编的机制
第八章 继承与多态
动态联编的基本步骤在编译过程中,扫描到表达式 pb->f()时,首先检查 f()是否为虚
函数(若f()不是虚函数,则按静态联编处理,在编译时必须为 f()确定对应的函数体代码);
( 2 )若f()为虚函数,则仅把与 f()同原型的虚函数的地址信息等列表待查;
( 3 )在程序运行阶段,当程序执行到表达式 pb->f()时,根据指针当前所指向的对象类属,来决定这时的 f()应执行哪个类中的哪个 f(),从而决定执行哪个函数体。
• 8.2 多态性• 8.2.2 动态多态的实现方法
• 2. 动态联编的机制
第八章 继承与多态
虚函数的动态联编的实现,主要依赖于下面一些条件:1 )基类 CB 可有多个派生类 CD1 , CD2 ,……, CDn;2 ) CB 类指针 pb 可以指向 CB 的对象,也可以指向 CD1 , CD2 ,
…… CDn的对象;3 ) CB 类和 CD1 , CD2 ,…… CDn 类可以有同样原型(而函数体各
异)的函数成员 f()(虚函数);
4 )运行着的程序根据查对当前指针 pb 所指向的对象是属于哪个类的,再决定到底执行哪个 f ()。
• 8.2 多态性• 8.2.2 动态多态的实现方法
• 2. 动态联编的机制
第八章 继承与多态
采用虚函数对于程序有益之处在于。1 )可使程序简单易读。
2 )它使得程序模块间的独立性加强。
3 )增加了程序的易维护性。
4 )提高了程序中“信息隐藏”的等级。
• 8.2 多态性• 8.2.4 纯虚函数和抽象基类
第八章 继承与多态
抽象基类的概念是虚函数概念的自然引申,它是虚函数使用的一个更理想的形式。
virtual 函数原型 =0;
若在虚函数的原型后加上“= 0” 字样而替掉函数定义体(没有具体的实现),则这样的虚函数称为纯虚函数。
virtual void print()=0;
• 8.2 多态性• 8.2.4 纯虚函数和抽象基类
第八章 继承与多态
含有纯虚函数的类称为抽象基类。
抽象基类的设计意义在于:
基类并不是完整的类,它在程序中只起到一种框架的作用,它所包含的是与定积分计算相关的数据成员,和计算定积分的函数成员的格式:函数名,参数表,返回类型等等。
• 8.2 多态性• 8.2.4 纯虚函数和抽象基类
第八章 继承与多态
class inte_algo
{
// 基类 inte_algo
protected:
……
public:
inte_algo (float left, float right, int steps)
{
// 基类构造函数……
}
virtual void integrate(void); // 基类中说明了一个虚函数 integrate
virtual ~inte_algo() {;};
};
• 示例
• 基类
• 8.2 多态性• 8.2.4 纯虚函数和抽象基类
第八章 继承与多态
class rectangle:public inte_algo
{
// 派生类 rectangle
public:
rectangle(float left,float right,
int steps):inte_algo (left,right,steps){}
virtual void integrate(void); // 虚函数 integrate
};
• 示例
• 派生类
• 小结(理论课)第八章 继承与多态
静态多态动态多态纯虚函数与抽象基类
• 小测验第八章 继承与多态
1. 选择题(单项选择题)1 、以下哪些是采用虚函数的好处:( )A. 可使程序简单易读 B. 使得程序模块间的独立性加强C. 增加了程序的易维护性 D. 提高了程序中“信息隐藏”的等级
2 、( )是一个在基类中说明的虚函数,它在该基类中没有定义,但要求任何派生类都必须定义自己的版本。A. 虚析构函数 B. 虚构造函数C. 纯虚函数 D. 静态成员函数3 、带有虚基类的多层派生类构造函数的成员初始化列表中都要列出虚基类的构造函数,这样将对虚基类的子对象初始化的次数是( )A. 与虚基类下面的派生类个数有关 B. 多次C. 二次 D. 一次
• 小测验第八章 继承与多态
1. 选择题(不定项选择题)1 、以下哪些是采用虚函数的好处:( ACD )A. 可使程序简单易读 B. 使得程序模块间的独立性加强C. 增加了程序的易维护性 D. 提高了程序中“信息隐藏”的等级
2 、( C )是一个在基类中说明的虚函数,它在该基类中没有定义,但要求任何派生类都必须定义自己的版本。A. 虚析构函数 B. 虚构造函数C. 纯虚函数 D. 静态成员函数3 、带有虚基类的多层派生类构造函数的成员初始化列表中都要列出虚基类的构造函数,这样将对虚基类的子对象初始化的次数是( D )A. 与虚基类下面的派生类个数有关 B. 多次C. 二次 D. 一次
• 课后作业第八章 继承与多态
【作业 1 】设计一个日期类 Date ,包括年、月、日等私有数据成员。要求实现日期的基本运算,如一日期加上天数、一日期减去天数、两日期相差的天数等。思路分析:在 Date 类中设计如下重载运算符函数: Date operator+(int days); 返回一日期加天数得到的日期 Date operator-(int days); 返回一日期减去天数得到的日期 int operator-(Date &b); 返回两日期相差的天数 在实现这些重载运算符函数调用以下私有成员函数: leap(int); 判断指定的年份是否为闰年 dton(Date &); 将指定日期转换为从 0 年 0 月 0 日起的天数 ntod(int); 将指定的 0 年 0 月 0 日起的天数转换为对应的日期
The End
第八章 继承与多态