编译时多态:函数重载的多态 和 运算符重载的多态
运行时多态:在程序执行前无法根据参数和函数名来确定该调用哪一个函数,必须在程序执行过程中,根据执行的情况动态的确定.它是根据类的继承关系和虚函数来实现的,目的是建立一种通用的过程.
虚函数:定义格式: vritual 返回类型 函数名(参数列表)
virtual 仅用于类定义中,在类外定义,不可加virtual.
当某一个类的一个成员函数被定义为虚函数时,则有该类派生出来的所有派生类中,该函数始终保持虚函数的特征.
当在派生类是重新定义虚函数时,不必加关键字virtual, 但重新定义时要求三同:参数表相同,函数名相同,返回类型相同.
如果参数列表或者返回值不同是重载(但是如果函数名和参数列表都相同,且在基类中该函数的返回值类型是基类的指针,派生类的该函数返回值是派生类指针,这种情况也是覆盖.这是一个例外)
该类的成员函数才能声明为虚函数
静态成员函数不能申明为虚函数,静态成员函数是一个类所共有的,不受限于一个类对象.
实现动态多态时:必须使用基类的指针变量或者引用,是该指针指向不同派生类的对象,并通过该指针指向虚函数,才能实现多态.
内联函数每个对象一个拷贝,无映射关系,不能作为虚函数.
虚函数可以定义为虚函数:在基类及其派生类中都动态分配内存空间时,必须把析构函数定义为虚函数,实现撤销对象时的多态性.((在基类的指针指向派生类的对象时,这个对象是动态new出来的是在delete 该基类指针事会调用派生类的析构函数).
纯虚函数(pure virtual function):
为什么会出现纯虚函数?
定义一个基类时,他遇到无法定义一个基类中虚函数的具体实现,他的实现依赖与派生类.
定义格式 virtual 返回类型 函数名(参数表)=0;
含有纯虚函数的基类是不能用来实例化对象的,所以含有纯虚函数的类称为抽象类.
抽象类:
是用来描述一类抽象的概念,比如说我们学过的数据类型,他就是一个抽象类,数据类型并不能来定义一个变量,只有具体到一个int , float , char,,等具体类型时才能定义对象,所以说dataType是一个抽象类,而int char float 才是dataType 的派生类,在抽象类中会有一些公共接口,他是派生类的公有特性,比如说,dataType可以用来定义一个变量,可以进行数据之间的加减乘除运算,而不同的数据类他们的加减乘除规则会有所差异,这就依赖于各自派生类的各自具体实现了,.所以说抽象类是用来定义一些公共接口(纯虚函数),然后再派生类中各自实现,这样在定义一个基类的指针,指向不同的派生类的对象,用指针调用纯虚函数时就可以去调不同派生类的纯虚函数就可以实现多态.
定义纯虚函数时注意:
纯虚函数"=0"表明程序员将不定义该函数,该函数声明是为派生类保留一个位置. "=0"本质上是将函数体的指针指向一个空指针NULL.
在派生类中必须有对纯虚函数重新定义才能用派生类来定义对象
.#ifndef _XXX_H#define _XXX_H//#include"utility.h"//#include<string.h>class Object{public: Object() {} virtual int compare(Object &s)=0; virtual void PRint()=0; virtual ~Object() {}};class String:public Object {public: String(const char *s) { str=new char[sizeof(s)+1]; strcpy(str,s); } void print() { cout<<str; } int compare(Object &s) { String &t=(String&)s; return strcmp(str,t.str); } ~String() { delete str; }private: char *str;};class List;class Node{public:friend List; Node() { info=NULL; next=NULL; } Node(Object *s) { info=s; next=NULL; } ~Node() { delete info; } private: Object *info; Node *next;};class List{public:List(){ head=tail=new Node();}void push_back(Object *s){ Node *t=new Node(s); tail->next=t; tail=t;}void push_front(Object *s){ Node *t=new Node(s); t->next=head->next; head->next=t; if(tail==head) tail=t;}void MakeEmpty(){ Node *t=head->next; Node *p=t; while(t) { head=t->next; delete t; t=t->next; }} void remove(Object *s){ Node *t=head->next; Node *p=t; while(t!=NULL&&t->info!=s) { p=t; t=t->next; } if(t==NULL) return ; p->next=t->next; delete t;}~List(){ MakeEmpty(); delete head;}void showlist(){ Node *t=head->next; while(t) { t->info->print(); cout<<"-->"; t=t->next; } cout<<"Over"<<endl;}private:Node *head;Node *tail;};#endif
新闻热点
疑难解答
图片精选