您的位置:首页 > 其它

虚函数与多态性,虚拟继承,纯虚函数及重载、覆盖、隐藏的区别

2014-05-29 15:58 197 查看
1.虚函数与多态性

首先我们通过一个例子来讲述一下虚函数与多态性:

class animal

{

public:

 void breathe()

 {

  cout<<"animal breathe!"<<endl;

 }

};

class fish:public animal

{

public:

 void breathe()

 {

  cout<<"fish bubble!"<<endl;

 } 

};

由上可以看出fish类继承了animal类,假设我们使用以下语句:

animal *pAn;

 fish fh;

 pAn=&fh;

 pAn->breathe();

结果输出的并不是:"fish bubble!",而是"animal breathe!"。并没有实现多态性。

下面我们分析一下fish对象的内存模型:



当我们构造fish类的对象时,首先要调用animal类的构造函数animal类对象,然后才调用fish类得构造函数完成自身部分的构造,从而拼接出一个完整的fish对象。当我们将fish类的对象转换成animal类型时,该对象就被认为是原对象整个内存模型的上半部分。所以输出为:"animal breathe!"。
如果我们将animal类得breathe()方法前面加上一个virtual关键字,程序的运行结果就是:"fish bubble!"。这就是C++中的多态性。用virtual关键字申明的函数叫做虚函数。

多态与非多态的实质区别就是函数地址是早绑定还是晚绑定。如果函数的调用,在编译器编译期间就可以确定函数的调用地址,并生产代码,是静态的,就是说地址是早绑定的。而如

果函数调用的地址不能在编译器期间确定,需要在运行时才确定,这就属于晚绑定。
C++中的多态性用一句话概括就是:在基类函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。
注意:当派生类中的函数也为虚函数时,也同样满足多态性,运行时同样将会根据对象的实际类型来调用相应的函数。

2.为什么要引入虚拟继承?

虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类C和类B,而类B、C都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B、C对A的继承定义为虚拟继承。代码实现如下:

class A;

class B:public virtual A;

class C:public virtual A;

classD:public B,public C;

3.C++中重载、覆盖、隐藏的区别

3.1成员函数被重载的特征:

(1)相同的范围(在同一个类中);

(2)函数名相同;

(3)参数不同;

(4)virtual关键字可有可无。

3.2. 覆盖是指派生类函数覆盖基类函数,特征:

(1)不同的范围(分别位于基类和派生类中);

(2)函数名相同;

(3)参数相同;

(4)基类函数中必须有virtual关键字。

3.3. 隐藏是指派生类的函数屏蔽了与其相同的基类函数,特征是:

(1)如果派生类的函数与基类的函数同名,但是参数不同,此时,不论有无virtual关键字,基类函数将被隐藏(注意与重载(发生在同一个类中)的区别)。

(2)如果派生类的函数与基类的函数同名,但是参数相同,此时,但基类中没有virtual关键字,基类函数将被隐藏(注意与覆盖的区别)。

4.纯虚函数

纯虚函数是一种特殊的虚函数,在许多情况下,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现类给该基类的派生类去做。这既是纯虚函数的作用。

纯虚函数的格式如下:

class<类名>

{

  virtual <类型><函数名>(<参数表>)=0;

}

凡是含有纯虚函数的类叫做抽象类。这种类不能声明对象,但可以定义指针,只是作为基类为派生类服务。在派生类中必须完全实现基类的纯虚函数,否则派生类也变成了抽象类,不能实例化对象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: