C++的虚函数与抽象类
当前位置:以往代写 > C/C++ 教程 >C++的虚函数与抽象类
2019-06-13

C++的虚函数与抽象类

C++的虚函数与抽象类

副标题#e#

1.虚函数

1.1虚函数的浸染

虚函数的浸染是答允在派生类中从头界说与基 类同名的函数,而且可以通过基类指针或引用来会见基类和派生类中的同名函数。

class Time{
 public:
  Time(int=0,int=0,int=0);
   void show();
 protected:
  int hour;
  int min;
   int sec;
};
class LocalTime:public Time{
 public:
   LocalTime(int=0,int=0,int=0,string="+8");
  void show();
  protected:
  string zone;
};
Time::Time(int h,int m,int s):hour (h),min(m),sec(s){}
void Time::show(){
  cout<<hour<<":"<<min<<":"<<sec& lt;<endl;
}
LocalTime::LocalTime(int h,int m,int s,string z):Time (h,m,s),zone(z){}
void LocalTime::show(){
  cout<<hour<<":"<<min<<":"<<sec& lt;<"@"<<zone<<endl;
}
int main(){
 Time t;
 LocalTime lt;
 Time *pt=&t;
 pt->show();
  pt=&lt;
 pt->show();
 system("PAUSE");
 return EXIT_SUCCESS;
}

功效:

0:0:0
0:0:0


#p#副标题#e#

这里 通过指针找到派生类,但无法挪用派生类show()。假如利用虚函数。

将基类Time中的 show()函数声明为虚函数, 其余稳定。

class Time{
 public:
  Time(int=0,int=0,int=0);
  virtual void show();

};

功效:

0:0:0

0:0:[email protected]+8

原来,基类指针是指向基 类工具的,假如用它指向派生类工具,则举办指针范例转换,将派生类工具的指针先转换为 基类指针,所以基类指针指向的是派生类工具中的基类部门。在措施修改前,是无法通过基 类指针去挪用派生类工具中的成员函数的。

虚函数打破这一限制,在派生类的基类部 分中,派生类的虚函数代替了基类本来的虚函数,因此在利用基类指针指向派生类工具后, 挪用虚函数时就挪用了派生类的虚函数。

1.2虚函数的利用要领

【1】在基类 用virtual声明成员函数为虚函数。这样就可以在派生类中从头界说此函数,为它赋予新的功 能,并能利便地被挪用。

【2】在派生类中从头界说此函数,要求函数名、函数(返 回)范例、函数参数个数和范例与基函数的虚函数沟通。假如在派生类中没有对基类的虚函 数重界说,则派生类简朴地担任直接基类的虚函数。

有一种环境破例,在这种环境下 派生类与基类的成员函数返回范例差异,但仍起到虚函数的浸染。即基类虚函数返回一个基 类指针或基类引用,而子类的虚函数返回一个子类的指针或子类的引用。

class Base{
 public:
  virtual Base *fun(){
    cout<<"Base's fun()."<<endl;
   return this;
  }
};
class Derived:public Base{
 public:
  virtual Derived *fun(){
   cout<<"Derived's fun ()."<<endl;
   return this;
  }
};
void test (Base &x){
 Base *b;
 b=x.fun();
}
int main(){
  Base b;
 Derived d;
 test(b);
 test(d);
 system ("PAUSE");
 return EXIT_SUCCESS;
}

功效:

Base's fun().
Derived's fun().

#p#副标题#e#

【3】C++规 定,当一个成员函数被声明为虚函数后,其派生类中的同名函数(切合2中界说的函数)都自 动成为虚函数。

【4】界说一个指向基类工具的指针变量,并使其指向同一类族中的 某个工具。通过该指针变量挪用此函数,此时挪用的就是指针变量指向的工具的同名函数。

1.3声明虚函数的限制

【1】只能用virtual声明类的成员函数,使它成为虚函 数,而不能将类外的普通函数声明为虚函数。

【2】一个成员函数被声明为虚函数后 ,在同一类族中的类就不能再界说一个非virtual的但与该虚函数具有沟通参数(个数与范例 )和函数返回值范例的同名函数。

【3】静态成员函数不能是虚函数,因为静态成员 函数不受限于某个工具。

【4】inline函数不能是虚函数,因为inline函数是不能在 运行中动态确定其位置的。纵然虚函数在类的内部界说,编译时,仍将其视为非inline的。

【5】利用虚函数,系统要有必然的空间开销。当一个类带有虚函数时,编译器会为 该类结构一个虚函数表(virtual function tanle,vtable),它是一个指针数组,存放每个虚 函数的进口地点。

2.虚析构函数

#p#分页标题#e#

class Time{
 public:
  Time(int=0,int=0,int=0);
  ~Time(){
   cout<<"Time destructor"<<endl;
  }
 protected:
  int hour;
  int min;
  int sec;
};
class LocalTime:public Time{
 public:
  LocalTime(int=0,int=0,int=0,string="+8");
   ~LocalTime(){
   cout<<"LocalTime destructor"<<endl;
  }
 protected:
  string zone;
};
Time::Time(int h,int m,int s):hour(h),min(m),sec(s){}
LocalTime::LocalTime(int h,int m,int s,string z):Time(h,m,s),zone(z){}
int main(){
 Time *p=new LocalTime;//指向派生类
 delete p;
 system ("PAUSE");
 return EXIT_SUCCESS;
}

功效:

Time destructor

#p#副标题#e#

从功效可以看出,执行的照旧基类的析构函数,而措施的本 意是但愿执行派生类的析构函数。此时将基类的析构函数声明为虚析构函数,

virtual ~Time(){
 cout<<"Time destructor"<<endl;
}

功效:

LocalTime destructor
Time destructor

假如将基类的析构函数声明为虚函数,由 该基类所派生的所有派生类的析构函数也自动成为虚函数。

把基类的析构函数声明为 虚函数的长处是,假如措施中delete一个工具,而delete运算符的操纵工具是指向派生类对 象的基类指针,则系统会挪用相应类的析构函数。

结构函数不能声明为虚函数。

3.纯虚函数

virtual void show()=0;//纯虚函数

这里将show()声明 为纯虚函数(pure virtual function)。纯虚函数是在声明虚函数时被“初始化” 为0的虚函数。

声明纯虚函数的一般形式为,

virtual 函数范例 函数名(参数 列表)=0;

纯虚函数没有函数体;最后的“=0”并不代表函数返回值为0, 它只起形式上的浸染,汇报编译器“这是纯虚函数”;这个一个声明语句,最后 有分号。

声明纯虚函数是汇报编译器,“在这里声明白一个虚函数,留待派生 类中界说”。在派生类中对此函数提供了界说后,它才气具备函数的成果,可以被挪用 。

纯虚函数的浸染是在基类中为其派生类保存了一个函数的名字,以便派生类按照需 要对它举办界说。

假如在一个类中声明白纯虚函数,而在其派生类中没有对该函数定 义,则该函数在派生类中仍为纯虚函数。

4.抽象类

将不消来界说工具而只作 为一种根基范例用作担任的类,称为抽象类(abstract class),由于它常用作基类,凡是称 为抽象基类。每每包括纯虚函数的类都是抽象类。

假如在派生类中没有对所有的纯虚 函数举办界说,则此派生类仍然是抽象类,不能用来界说工具。

可以界说指向抽象类 数据的指针变量。当派生类成为详细类后,就可以用这个指针指向派生类工具,然后通过该 指针挪用虚函数。

    关键字:

在线提交作业