1、介绍:同样的消息给各种不同的对象时,会产生多种形式的结果,这就是多态性。 注: 2、多态性能设计和实现更具扩展性的软件系统。 (一)、静态绑定:系统在编译时就确定如何实现某一动作; 4、多态发生的两个要素: 1、派生类对象可以被当做它的基类对象来处理。 不能把基类对象当做任何一个派生类的对象来处理。 2、调用的函数功能是由调用函数的句柄(指针或引用)决定的,而不是由句柄所指向的对象类型决定。 3、通过基类指针调用派生类的成员函数: 1、基类指针指向派生类对象,并试图访问只在派生类中拥有的成员函数,会产生编译错误(派生类中有的成员函数基类中没有)。 例如: 以上情况可以用强制类型转换的方法,把基类指针commissionEmployeePtr转换成派生类指针。 4、虚函数(动态绑定) 虚函数的定义在函数原型前加关键字virtual.函数原型和实现都加关键字。 注意:动态的绑定只发生句柄必须是基类的指针或引用,发送消息的函数是虚函数;如果是一个确定的基类对象和派生类对象,没有动态的性质。 举例: (1)、派生类中重载的函数必须和在基类中的具有相同的原型,如以上的print函数。 1、抽象类:有些类通常在类的继承层次结构中作为基类,从来不实例化任何对象,这种类称为抽象类。 注: 2、通过声明类的一个或多个virtual函数为纯虚函数,就能定义其为抽象类。 3、纯虚函数不提供函数的具体实现,每个派生的具体类必须重写所有类的纯虚函数的定义。 (1)、试图实例化抽象类的对象将导致编译错误。 1、向下强制类型转换 返回运算符操作数类型的信息(要写出类型的名字) 1、将基类的析构函数声明为虚析构函数,这样就会使所有派生类的析构函数自动成为虚析构函数(即使它们与基类析构函数名不同)。 在继承层次关系中,在某一层出现开辟空间的操作,则要把析构函数声明为虚析构函数。 3、构造函数不能是virtual函数。 1、类模板和模板类 例如:建立一个用来实现求和的类模板 3、类模板中的成员函数可以在类模板体外定义。此时,若成员函数中有类型参数存在,则C++有一些特殊的规定: 例如,上例这种成员函数Three在类模板体外定义时,应该写成:
面向对象编程:多态性(C++)
一、简介
(1)、继承层次中的对象
(2)、消息是重载的函数 (因为重载的函数的签名才会一样,即函数名和类型)
3、多态性的两个底层技术:虚函数和动态绑定
(二)、动态绑定:系统在运行时动态实现某一动作(在编译时不确定执行哪段代码)。
(1)、虚函数的调用;
(2)、指向派生类对象或引用的基类指针(它们不同时刻指向不同派生类的对象)。二、类继承层次中对象之间的关系
GraduateStudent gs;//实例化一个派生类对象gs Student s = gs;//基类对象指向派生类对象 Student &t = gs;//基类的引用可以指向派生类 Student *p = &gs;//基类的指针可以指向派生类对象 gs = s;//错误,不可以派生类对象指向基类对象 GraduateStudent *pGs = &s;//错误,派生类指针不可以指向基类对象
例如:/*一个基类指针指向派生类*/ commissionEmployeePtr = &basePlusCommissionEmployee;//commissionEmployeePtr为基类指针,basePlusCommissionEmployee为派生类对象 commissionEmployeePtr -> print();//print函数功能是由基类决定的,不是派生类。找句柄所属类的对象。
2、显示把基类指针强制转化为派生类指针(向下强制类型转换),可以通过指向派生类对象的基类指针访问只在派生类中拥有的成员。/*getBaseSalary(),setBaseSalary()为派生类中的函数;commissionEmployeePtr为基类指针*/ double baseSalary = commissionEmployeePtr ->getBaseSalary(); commissionEmployeePtr -> setBaseSalary(500);//两条语句错误。
利用虚函数,调用哪个版本的虚函数就由句柄所指向的对象类型决定,而非句柄的类型。/*以下print()函数全是virtual函数*/ commissionEmployeePtr = &commissionEmployee;//基类指针指向基类对象 commissionEmployeePtr -> print();//此处的print()自然找基类的print()执行 basePlusCommissionEmployeePtr = &basePlusCommissionEmployee;//派生类指针指向派生类对象 basePlusCommissionEmployeePtr -> print();//print()找派生类中的print()操作 commissionEmployeePtr = &basePlusCommissionEmployee;//基类指针指向派生类对象 commissionEmployeePtr -> print();//此处print()将调用派生类中的print()函数
(2)、用虚函数进行 动态绑定,只能通过指针或引用句柄来实现。
(3)、一旦一个函数声明为virtual,那么从整个继承层次的那一点向下的所有类中,它将保持virtual的,即使当派生类重写此函数时并没有显示的将它声明为virtual.
(4)、当派生类选择不重写从其基类继承而来的virtual函数时,派生类就会简单地继承它的基类的virtual函数的实现。三、抽象类和纯virtual函数
(1)、抽象类是不完整的,派生类必须定义缺少的部分。
(2)、构造一个抽象类的目的就是为其它的类提供合适的基类。
(3)、能实例化对象的类称为具体类,具体类实现了它所定义的每一个成员函数。纯虚函数定义: virtual void draw() = 0;
4、抽象类为类层次结构中的各种类定义公共的接口。抽象类包含一个或多个纯虚函数,这些函数必须在派生类中重写。
(2)、未能在派生类中重写纯virtual函数,然后试图实例化这个派生类对象将产生编译错误。四、应用向下强制类型转换
BasePlusCommissionEmployee *derivedPtr = dydynamic_cast<BasePlusCommissionEmployee *> (employee[i]); 返回值:derivedPtr不为零,说明其指向一个BasePlusCommissionEmployee 对象 否则,它指的不是这种BasePlusCommissionEmployee 的对象。
cout << typeid(int).name() << endl; 或 int a ; cout << typeid(a).name() << endl; 输出的都是int
五、virtual析构函数
2、当基类指针指向其派生类对象,用delete删除基类指针时,就会调用其所指对象(即其对应派生类)的析构函数,所有类的析构函数将执行,如果派生类要求执行析构函数,那么基类必须声明为虚析构函数。class A { public: A() {} virtual ~A(); }; A::~A() { cout << "~A"<< endl; }
class B:public A { public: B(int); virtual~B(); private: int *b; }; B::B(int n) { b = new int(n);//实例化B类对象 } B::~B() { cout << "~B" << endl; delete b;//要回收开辟的 }
六、(补充)类模板和模板类
所谓类模板,实际上是建立一个通用类,其数据成员、成员函数的返回类型和形参类型不具体指定,用一个虚拟的类型来代表。
使用类模板定义对象时,系统会根据实参的类型(模板实参)来取代类模板中虚拟类型从而实现了不同类的功能。
2、定义一个类模板,格式如下:template<typename Type> class 类名 { 类成员函数 } 1、template是一个声明模板的关键字 2、Type是类型参数(自定义) 或 template<class Type> class 类名 { 类成员函数 }
类模板定义对象时用以下形式类模板名<实际类型名> 对象名[{实参表列}] int main() { Three <int> sum3_1(3,5,7);//用类模板定义对象sum3_1,此时T被int取代 Three <double> sum3_2(12.34,34.56,56.78);//用类模板定义对象sum3_2,此时T被double取代 cout << "三个整数之和是" << sum3_1.sum() << endl; cout << "三个双精度数之和是:" << sum3_2.sum() << endl; return 0;
(1)、需要在成员函数定义之前进行模板声明;
(2)、在成员函数名前缀上“类名<类型参数>::”
在类模板体外定义的成员函数的一般形式如下:template <typename 类型参数> 函数类型 类名<类型参数>::成员函数(形参表) { ........... }
template<typename T> T Three<T>::sum() { return x + y + z; }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算