资源描述
单击此处编辑母版标题样式,第一级,第二级,*,多态,第九章,回顾,继承,访问控制,继承中的构造函数和析构函数,函数覆盖,2,目标,虚函数,纯虚函数,抽象类,动态绑定,虚析构函数,3,虚函数,基类的指针可以指向派生类的对象,但调用的函数却是基类的函数,虚函数可以解决这个问题,4,示例,2-1,#include ,class Shapes,public:,void draw(),/,基类中的函数,cout, ,绘制基本形状,n;,;,class Circle : public Shapes,private:,int radius;,public:,void draw(),/,在派生类中重新定义,cout, ,绘制圆形,n;,;,5,示例,2-2,class Square : public Shapes,private:,int length;,public:,void draw(),/,在派生类中重新定义,cout,draw();,ptr,= ,ptr,-draw();,调用,Shapes,的,draw(),方法,6,虚函数,的定义,希望使用,draw( ),函数绘制不同对象,draw( ),函数必须在基类中被声明为虚函数,virtual,void draw()/,基类中的虚函数,cout, ,绘制基本形状,n;,7,虚函数的覆盖,派生类替换基类提供的虚函数实现,编译器确保调用函数的正确版本,8,演示,使用虚函数演示前面的例子,9,注意要点,virtual,关键字,虚函数必须在声明它的类中有定义,在派生类中重新定义的虚函数必须具有相同的参数,10,纯虚函数,2-1,基类无法(或没有必要)提供虚函数的实现,将虚函数声明为纯虚函数,virtual,void print(),= 0,;,11,纯虚函数,2-2,派生类要创建对象,必须实现纯虚函数,不能创建含有纯虚函数的类的对象,12,抽象类,2-1,包含纯虚函数的类,只能用作基类,不能创建抽象类的对象,class,类名,virtual,类型 函数名,(,参数表,) = 0;,;,13,抽象类,2-2,继承了抽象类而没有提供纯虚函数的实现,这个类也是抽象类,抽象类提供接口而不暴露实现细节,在许多商业用途的库和应用程序框架中使用,14,动态绑定,2-1,成员函数调用中代码地址的确定,非虚成员函数是根据指向对象的指针的类型静态地(在编译时)选择,虚成员函数是动态(在运行时)解析的。根据对象的类型而不是根据指向对象的指针的类型来动态地(在运行时)选择,15,动态绑定,2-2,使用虚函数 ,系统将使用动态绑定,在程序设计中提供更强的功能和灵活性,处理过程中占用一些开销,16,虚析构函数,2-1,调用析构函数是为了释放由构造函数分配的内存空间,如果基类的析构函数是非虚的,则不能用指向派生类的指针调用派生类的析构函数,需要虚析构函数,17,虚析构函数,2-2,虚函数绑定到与对象所属的类,而不是与指针所对应的类,派生类的实例总是包含一个基类的实例,需要调用这两个类的析构函数以确保所有空间都被释放,注意:构造函数不能是虚函数,18,示例,2-1,#include ,class Alpha,private:,char*,alpha_ptr,;,public:,Alpha()/,构造函数不能是虚函数,alpha_ptr,= new char5;,virtual Alpha(),/,虚析构函数,delete,alpha_ptr,;,cout, Alpha,的析构函数, ,endl,;,;,19,示例,2-2,class Beta : public Alpha,private:,char*,ptrderived,;,public:,Beta(),ptrderived,= new char100;,Beta(),delete,ptrderived,;,cout, Beta,的析构函数, ,endl,;,;,void main(),Alpha *,ptr,= new Beta;,delete,ptr,;,20,总结,虚函数,纯虚函数,抽象类,动态绑定,虚析构函数,21,
展开阅读全文