C++虚函数的作用

上一篇 / 下一篇  2012-09-26 13:42:34 / 个人分类:C++

51Testing软件测试网;Wqb2i xt6r8B

  最近面试C++研发的职位,面试官们问到最多的问题的什么是虚函数,虚函数的作用,为什么要有虚函数以及虚函数的使用等等相关的问题。经过各种资料的查找,我觉得还是要从头到尾的重新认识一下虚函数。51Testing软件测试网N-Tx-ms

51Testing软件测试网'z)E4?eUN:b b9G(B

  我们都知道,C++为了与c语言能够兼容,C++做出了很大的牺牲,包括保留了struct关键字,还有编译期间添加了好多隐藏的代码。但是虚函数却不能与c语言实现兼容。而且有了虚函数,类的数据对象布局都发生了巨大的变化。这些暂时不说,还是回到上面的问题吧!

*qXvST-l0

x2C3b`nd^'\~Q+a0   什么是虚函数?我们都知道函数可以分为三种,一种是类的成员函数(member function),又可分为非静态成员函数(non-static member function),以及静态成员函数(static member function),而还有一种非类的成员函数(non-member function)。在类的非静态成员函数中又可以分为普通的函数以及虚函数。根据这种函数的分类,就知道了函数绝对是不能同时为虚函数以及静态成员函数 的。对虚函数还可以继续细分,一是纯虚函数,一种就是普通的虚函数。纯虚函数必须在普通的虚函数基础上加上“=0”,同时普通的虚函数必须要有函数的实 现。而纯虚函数默认情况是只有定义,而无需实现的,即只是定义一个接口(当然也可以实现,这时实现认为是默认的一种状态显示),同时包含了纯虚函数的类表 明该类时一个抽象类,不能定义该类的对象,也就是说该类被定义成基类,是要被继承的,通过继承类来完成基类对象的生成。最后,强调一下,虚函数必须有一个 关键字来修饰:virtual ,同时不能有static修饰。51Testing软件测试网5i+] i?l"OM9uC)F

51Testing软件测试网[eNz/ZV

  虚函数的作用?我们知道面向对象语言的意义是让程序用一种符合人的思维 来运行,而虚函数在C++面向对象语言的实现中起着举足轻重的作用。简而言之,虚函数的作用就是实现“动态联编”,也就是在程序的运行阶段动态地选择合适 的成员函数。具体的实现方式是:在定义了虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参 类型。以实现统一的接口,不同定义过程。如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数。编译器在编译过程中发现类的函数名前的关键字 virtual后,会自动将其作为动态联编处理,即在程序运行时动态地选择合适的成员函数,具体的实现机制下篇再讲。

J,RbL!l3Eulo051Testing软件测试网9v0X5kn PC|v B

  这里提前说一下,类的静态成员函数与非类的成员函数对于类对象来说,访问函数的效率相当,都是在编译器确定,而虚函数需要在运行期确定,所以效率较低(符合上帝是公平的规律吧)。

!}X%t e0C PX4id M0

7|W%gg@da9Y0   虚函数的使用?正确的使用虚函数是一个比较简单的问题。要实现动态联编,即只能用一个基类的指针或者引用来指向派生类对象,为什么必须要这样,见后面的 虚函数实现机制。而把派生类对象赋值或者拷贝给基类的对象,只能实现派生类隐式转换成基类,即在编译器完成了派生类的截断,不能达到动态联编得作用。还是 直接上代码吧!(估计大家看了这么多的文件,对代码已经很期待了,哈哈!)

^N,K;Y/e V0
51Testing软件测试网D&u ? z'a q? KGb

#include<iostream.h>51Testing软件测试网^]8r;[0B(eWf]Z)UU
class Cshape51Testing软件测试网9g3p,L2}M8R:Y
{51Testing软件测试网 l#]1^9] B%f"aM-c)P6Y
public:51Testing软件测试网0MQ\xaU
   void SetColor( int color) { m_nColor=color;}
#V;p*LZ:j`#z,wn6D0   void virtual Display( void) { cout<<"Cshape"<<endl;51Testing软件测试网3k }O*DdO3RC
}51Testing软件测试网I(W} Q5v#P#d(BV/AF
private:51Testing软件测试网6C3S2@:G-Mv R
   int m_nColor;51Testing软件测试网 u4e6STkN%h7z
};51Testing软件测试网(v6V{)Tp%qg!C
class Crectangle: public Cshape
dBG&U0a)]y'hS#o0{
\0f%D%^;O0public:
tx5n*V3Dx O0   void virtual Display( void) { cout<<"Crectangle"<<endl; }51Testing软件测试网{$Q.EU \ kj$W
};51Testing软件测试网~Z4Und
class Ctriangle: public Cshape
eHu3};o,H0{51Testing软件测试网!O%l%A `#}.R-o)JCN
 void virtual Display( void)
d SS ~OG6v(_m0  {     cout<<"Ctriangle"<<endl;  }51Testing软件测试网S*e)pl+\X/K5g
};51Testing软件测试网p ]J2z [8y(M
class Cellipse :public Cshape
:eP;EAy|^#o0{51Testing软件测试网k*TjZ*J*a
public:51Testing软件测试网S^Y'J8yJ.Sx;f.zg#T%T*?
   void virtual Display(void)
.]Qo)?7^} s fl6^l8P0   {       cout<<"Cellipse"<<endl;   }51Testing软件测试网B@ L@;W C-[$J|
};
Q E:MeP/dBHA0void main()51Testing软件测试网$Z+qRlp3l
{
qqq_K?n1O3|(Q0  Cshape obShape;51Testing软件测试网6gtB T0T Lj-T
  Cellipse obEllipse;
U)\-o/F3KCZ(@*PN&`0  Ctriangle obTriangle;51Testing软件测试网_ MQ d4`aJ?!_,])X!c
  Crectangle obRectangle;51Testing软件测试网j0Q'm?u%R.|t'~
  Cshape * pShape[4]=
A8U8o+OS7NKJ@0  { &obShape, &obEllipse,&obTriangle, & obRectangle };51Testing软件测试网 Xl"H p+H(M6Efx
   for( int I= 0; I< 4; I++)51Testing软件测试网S*Xq1AL
     pShape[I]->Display( );

#h p/q"f(Ebl~-x;a051Testing软件测试网Lad A5l2Vbm`;t2\

}51Testing软件测试网 E2j*s)g,w U%v:i

51Testing软件测试网$jN1{f2s9Y3G'`

  本程序运行结果:

@#s!l5xFWg0

&B"U,W4S V/g0  Cshape
*W/a8XYcH Rx0  Cellipse
1`)k[*t-{@0  Ctriangle51Testing软件测试网&c*c$WRHQ-}A;rT
  Crectangle
51Testing软件测试网%^^"V}GD \$[

51Testing软件测试网%D(W+p/t~Jr;O nf

  如果上面的程序main函数中改为:51Testing软件测试网PK {,H4c3GBf

Cshape  pShape[4]={ obShape, obEllipse,obTriangle, obRectangle };51Testing软件测试网m,|;?L-Z)vh!DC
for( int I= 0; I< 4; I++)
~'p?laNB2s0pShape[I].Display( );

8m'T)Bu1s o,F0  那么程序运行结果会变成:51Testing软件测试网([~ U^6|*c

51Testing软件测试网d$`jC!P"|#Ci,RS

  Cshape
{#K2A(O"C;hZ ~%_0  Cshape
s%`9a2e1h0  Cshape
&D1zbEck[D,~0  Cshape

B,y+b` i'Z*?K0

_?:?,W-aF D0  通过例子的运行结果,如何使用虚函数就一目了然了吧!51Testing软件测试网Mm&e6uIp


TAG:

 

评分:0

我来说两句

Open Toolbar