C++虚函数的作用

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

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

(L~1E+K,A*@8Npv0

3?$zpSz Cd]T0  我们都知道,C++为了与c语言能够兼容,C++做出了很大的牺牲,包括保留了struct关键字,还有编译期间添加了好多隐藏的代码。但是虚函数却不能与c语言实现兼容。而且有了虚函数,类的数据对象布局都发生了巨大的变化。这些暂时不说,还是回到上面的问题吧!51Testing软件测试网(X*H'CG {

51Testing软件测试网h"m)c2s2XT K6~ n

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

"LC|rE5k051Testing软件测试网b7pG&f#w(Y(_

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

9`w\2t5btrN051Testing软件测试网w7{1D4G7~Eg5u

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

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

%k u*X!f:hY0#include<iostream.h>51Testing软件测试网P:C&Tl"h9b
class Cshape51Testing软件测试网\f ?s{+nL;PI
{51Testing软件测试网5p{Z6rjo9Y-T
public:51Testing软件测试网(u8o} F{m1^!tg5C
   void SetColor( int color) { m_nColor=color;}
3oz+`s.MqWW0   void virtual Display( void) { cout<<"Cshape"<<endl;
O!jP\$r P4`!Z hD0}
]a LO!Z6~ ?0private:
s-x g;YI0QK6zl@U0   int m_nColor;51Testing软件测试网f0_3tK1~\ b"O
};
2no{z4S M#]0class Crectangle: public Cshape51Testing软件测试网Jk4M gk @jI
{51Testing软件测试网Ak0N+WNI
public:
+R _F'eTsGj5K0   void virtual Display( void) { cout<<"Crectangle"<<endl; }
*zTw(Xv5Q'i N@9e0};51Testing软件测试网9lIx:|/rZB w7t
class Ctriangle: public Cshape
2N y&ecjK0{
)t!MoP2G@wn0 void virtual Display( void)51Testing软件测试网(t$q$Y s5M
  {     cout<<"Ctriangle"<<endl;  }
:E Qqd6iwi0};51Testing软件测试网aT@ s7g\
class Cellipse :public Cshape
-xk(f Z[#x-L0{
/] k8u Lg7Za'\? ^0public:
GH~Ce7^0   void virtual Display(void)
7Lt5cxA.?sbv0   {       cout<<"Cellipse"<<endl;   }51Testing软件测试网7p'? GK,D8B&V
};
R R%D^ N)p8g bb0void main()51Testing软件测试网&e/m9i,ls WkF#LIU3f
{51Testing软件测试网hCS&E2~~b
  Cshape obShape;51Testing软件测试网~:X_/r N x*r
  Cellipse obEllipse;51Testing软件测试网X'mLWi6V`!xv$r1`
  Ctriangle obTriangle;51Testing软件测试网)I6D6b Z&E+|C~t
  Crectangle obRectangle;
2O P'L!F"jv+t~7U0  Cshape * pShape[4]=
,Yx"u?] g;[0  { &obShape, &obEllipse,&obTriangle, & obRectangle };
r6rc8cJ^{Yv$t0   for( int I= 0; I< 4; I++)51Testing软件测试网{y.^c.m'e-w j"b~'XG
     pShape[I]->Display( );

5{#Z'X;g z0

1h[!^8ll1v6m @'M0}51Testing软件测试网 S5?2k@-ogo4FrK

51Testing软件测试网6EDMGz*q$t

  本程序运行结果:

4T h^,yO%F0

,ZS;l"]8C,\n0  Cshape
4B8`RAGz QW0  Cellipse51Testing软件测试网 y @+i/W _z
  Ctriangle51Testing软件测试网9leF x L%u7A
  Crectangle
51Testing软件测试网H D8u"jNbv+g v9}

'g_m4_ K;z8I0  如果上面的程序main函数中改为:51Testing软件测试网 {cE_(QU

Cshape  pShape[4]={ obShape, obEllipse,obTriangle, obRectangle };51Testing软件测试网]m#Z&p k.v{9I1S*Y
for( int I= 0; I< 4; I++)
)J zU)JZ0pShape[I].Display( );
51Testing软件测试网o.wsa7xli A

  那么程序运行结果会变成:51Testing软件测试网X;|1Y5F6Um|(A

51Testing软件测试网2iS;ID.NIBdX

  Cshape
VNN$E)v8A0  Cshape51Testing软件测试网q9L u s|8sL&{:z
  Cshape51Testing软件测试网.Ok1ku ^
  Cshape
51Testing软件测试网v\o?6P f\+C

51Testing软件测试网vy f\u

  通过例子的运行结果,如何使用虚函数就一目了然了吧!

1E+`F.c9Z?s CO0

TAG:

 

评分:0

我来说两句

Open Toolbar