C++虚函数的作用
上一篇 /
下一篇 2012-09-26 13:42:34
/ 个人分类:C++
51Testing软件测试网;Wqb2ixt6r8B 最近面试C++研发的职位,面试官们问到最多的问题的什么是虚函数,虚函数的作用,为什么要有虚函数以及虚函数的使用等等相关的问题。经过各种资料的查找,我觉得还是要从头到尾的重新认识一下虚函数。51Testing软件测试网 N-Tx-ms
51Testing软件测试网'z)E4?eUN:b b9G(B 我们都知道,C++为了与c语言能够兼容,C++做出了很大的牺牲,包括保留了struct关键字,还有编译期间添加了好多隐藏的代码。但是虚函数却不能与c语言实现兼容。而且有了虚函数,类的数据对象布局都发生了巨大的变化。这些暂时不说,还是回到上面的问题吧!
*qXvST-l0x2C3b`nd^'\~Q+a0
什么是虚函数?我们都知道函数可以分为三种,一种是类的成员函数(member function),又可分为非静态成员函数(non-static
member function),以及静态成员函数(static member
function),而还有一种非类的成员函数(non-member
function)。在类的非静态成员函数中又可以分为普通的函数以及虚函数。根据这种函数的分类,就知道了函数绝对是不能同时为虚函数以及静态成员函数
的。对虚函数还可以继续细分,一是纯虚函数,一种就是普通的虚函数。纯虚函数必须在普通的虚函数基础上加上“=0”,同时普通的虚函数必须要有函数的实
现。而纯虚函数默认情况是只有定义,而无需实现的,即只是定义一个接口(当然也可以实现,这时实现认为是默认的一种状态显示),同时包含了纯虚函数的类表
明该类时一个抽象类,不能定义该类的对象,也就是说该类被定义成基类,是要被继承的,通过继承类来完成基类对象的生成。最后,强调一下,虚函数必须有一个
关键字来修饰:virtual ,同时不能有static修饰。51Testing软件测试网5i+]i?l"OM9u C)F
51Testing软件测试网[eN z/ZV 虚函数的作用?我们知道面向对象语言的意义是让程序用一种符合人的思维
来运行,而虚函数在C++面向对象语言的实现中起着举足轻重的作用。简而言之,虚函数的作用就是实现“动态联编”,也就是在程序的运行阶段动态地选择合适
的成员函数。具体的实现方式是:在定义了虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参
类型。以实现统一的接口,不同定义过程。如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数。编译器在编译过程中发现类的函数名前的关键字
virtual后,会自动将其作为动态联编处理,即在程序运行时动态地选择合适的成员函数,具体的实现机制下篇再讲。
J,RbL!l3Eulo051Testing软件测试网9v0X5knPC|v
B 这里提前说一下,类的静态成员函数与非类的成员函数对于类对象来说,访问函数的效率相当,都是在编译器确定,而虚函数需要在运行期确定,所以效率较低(符合上帝是公平的规律吧)。
!}X%te0C PX4id M07|W%gg@da9Y0
虚函数的使用?正确的使用虚函数是一个比较简单的问题。要实现动态联编,即只能用一个基类的指针或者引用来指向派生类对象,为什么必须要这样,见后面的
虚函数实现机制。而把派生类对象赋值或者拷贝给基类的对象,只能实现派生类隐式转换成基类,即在编译器完成了派生类的截断,不能达到动态联编得作用。还是
直接上代码吧!(估计大家看了这么多的文件,对代码已经很期待了,哈哈!)
^N,K;Y/eV051Testing软件测试网D&u?z'a q?
KG b #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*V3DxO0 void virtual Display( void) { cout<<"Crectangle"<<endl; }51Testing软件测试网{$Q.EU\kj$W };51Testing软件测试网~Z4U nd class Ctriangle: public Cshape eHu3};o,H0{51Testing软件测试网!O%l%A `#}.R-o)JCN void virtual Display( void) dSS ~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'J8y J.Sx;f.zg#T%T*? void virtual Display(void) .]Qo)?7^}
sfl6^l8P0 { cout<<"Cellipse"<<endl; }51Testing软件测试网B@
L@;W C-[$J| }; QE:MeP/d BHA0void main()51Testing软件测试网$Z+qRlp3l { qqq_K?n1O3|(Q0 Cshape obShape;51Testing软件测试网6gt B
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"Hp+H(M6Efx for( int I= 0; I< 4; I++)51Testing软件测试网S*Xq1AL pShape[I]->Display( ); #h
p/q"f(Ebl~-x;a051Testing软件测试网LadA5l2Vbm`;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
Crectangle51Testing软件测试网%^^"V}GD\$[
51Testing软件测试网%D(W+p/t~ Jr;Onf 如果上面的程序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"|#C i,RS Cshape
{#K2A(O"C;hZ~%_0 Cshape
s%`9a2e1h0 Cshape
&D1zbEck[D,~0 Cshape
B,y+b` i'Z*?K0_?:?,W-aFD0 通过例子的运行结果,如何使用虚函数就一目了然了吧!51Testing软件测试网Mm&e6uIp
收藏
举报
TAG: