C++虚函数的作用
上一篇 /
下一篇 2012-09-26 13:42:34
/ 个人分类:C++
E4REYUuU$rt0 最近面试C++研发的职位,面试官们问到最多的问题的什么是虚函数,虚函数的作用,为什么要有虚函数以及虚函数的使用等等相关的问题。经过各种资料的查找,我觉得还是要从头到尾的重新认识一下虚函数。
(L~1E+K,A*@8Npv03?$zp Sz
Cd]T0 我们都知道,C++为了与c语言能够兼容,C++做出了很大的牺牲,包括保留了struct关键字,还有编译期间添加了好多隐藏的代码。但是虚函数却不能与c语言实现兼容。而且有了虚函数,类的数据对象布局都发生了巨大的变化。这些暂时不说,还是回到上面的问题吧!51Testing软件测试网(X*H'CG {
51Testing软件测试网h"m)c2s2XTK6~n
什么是虚函数?我们都知道函数可以分为三种,一种是类的成员函数(member function),又可分为非静态成员函数(non-static
member function),以及静态成员函数(static member
function),而还有一种非类的成员函数(non-member
function)。在类的非静态成员函数中又可以分为普通的函数以及虚函数。根据这种函数的分类,就知道了函数绝对是不能同时为虚函数以及静态成员函数
的。对虚函数还可以继续细分,一是纯虚函数,一种就是普通的虚函数。纯虚函数必须在普通的虚函数基础上加上“=0”,同时普通的虚函数必须要有函数的实
现。而纯虚函数默认情况是只有定义,而无需实现的,即只是定义一个接口(当然也可以实现,这时实现认为是默认的一种状态显示),同时包含了纯虚函数的类表
明该类时一个抽象类,不能定义该类的对象,也就是说该类被定义成基类,是要被继承的,通过继承类来完成基类对象的生成。最后,强调一下,虚函数必须有一个
关键字来修饰:virtual ,同时不能有static修饰。
"L C|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{Z6r jo9Y-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!j P\$rP4`!Z hD0} ]a LO!Z6~?0private: s-xg;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'eTsG j5K0 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$Ys5M { cout<<"Ctriangle"<<endl; } :E
Qq d6iwi0};51Testing软件测试网aT@ s7g\ class Cellipse :public Cshape -xk(fZ[#x-L0{ /]
k8u
Lg7Za'\?
^0public: GH~Ce7^0 void virtual Display(void) 7L t5cxA.?sbv0 { cout<<"Cellipse"<<endl; }51Testing软件测试网7p'?GK,D8B&V }; R
R%D^
N)p8g
bb0void main()51Testing软件测试网&e/m9i,lsWkF#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 z01h[!^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软件测试网9l eF
x L%u7A
Crectangle51Testing软件测试网H
D8u"jNbv+g v9}
'g_m4_K;z8I0 如果上面的程序main函数中改为:51Testing软件测试网
{c E_(QU
Cshape pShape[4]={ obShape, obEllipse,obTriangle, obRectangle };51Testing软件测试网 ] m#Z&pk.v{9I1S*Y for( int I= 0; I< 4; I++) )JzU)J Z0pShape[I].Display( ); |
51Testing软件测试网o.wsa7xli
A 那么程序运行结果会变成:51Testing软件测试网X;|1Y5F6Um|(A
51Testing软件测试网2iS;ID.NIBdX Cshape
VNN$E)v8A0 Cshape51Testing软件测试网q9L u
s|8s L&{:z
Cshape51Testing软件测试网.O k1ku
^
Cshape51Testing软件测试网v\o?6P f\+C
51Testing软件测试网v y f\u 通过例子的运行结果,如何使用虚函数就一目了然了吧!
1E+`F.c9Z?s
CO0
收藏
举报
TAG: