从C成长为C++程序员(2) ---- 函数指针与虚函数

(在我上传的资源中,可以找到应用下面技术的C++源代码)

函数指针一直以来是C 语言中的一个难点。什么情况下可以用函数指针?怎么用?下面给出一个简单的例子:

我们都知道数字电路中有 与门,或门,非门等逻辑电路,下面假设我们要画出他们的图形:

一般的程序员会这样写:

Void Draw(int type)

{

Switch(type)

{

Case AND:

DrawAnd();

Break;

Case OR:

DrawOr();

Break;

Case NOT:

DrawNot();

Break;

Default:

Break;

};

}

 

type的种类达到几十个时,程序的效率就越来越低了。因为上面的语句编译器会解释成如下语句(最后一种情况要经过很多次判断才能执行到)

If(type==AND)

       DrawAnd();

Else if(type==OR)

       DrawOr();

Else if(type==NOT)

       DrawNot();

………

 

为了提高效率,我们可以写成下面的方式:

typedef void (*DrawFunction)(void);/*定义函数指针类型*/

 

const DrawFunction  pDrawFunction[ ] =

{

       DrawAnd;

       DrawOr;

       DrawNot;

       ……

}

Enum

{

AND, OR, NOT, …….

}

Void Draw(int type)

{

       pDrawFunction[ type ]( );

}

 

上面的代码在减少了代码量的情况下,反而提高执行效率。这就告诉我们程序员:空间换时间只是一个相对概念,不要理解成多的代码量一定能换取到运行时间。

 

那么C语言中的函数指针和C++中的虚函数有什么联系呢?

我刚开始写MFC程序时,总是想用C语言的函数指针的方法去实现类似上面的情况,但是,确连编译都通不过。后来,我才认识到,C++在自身的特性上就实现了类似上面的方法。C++的这种特性就是“虚函数”。

C++的书上,提到“虚函数”,一般会说“虚函数实在运行时动态绑定的,通过编译时生成的虚函数表,可以找到对应的函数”

这样的说法和上面的例子对应起来,就更好理解了。所谓虚函数表,就是形成了类似上面的一个数组(具体实现上应该没有这么简单),然后通过类的ID号,就可以定位到自己的函数了。

我们还是以上面为例,在C++中如何实现画图:

定义一个基类:

Class CItemBase : public CObject

{

Public :

       Virtual void draw(void);

};

然后分别定一 CAnd, COr, CNot….

Class CAnd: public CItemBase

{

Public :

       Virtual void draw(void);

}

Class COr: public CItemBase

{

Public :

       Virtual void draw(void);

}

Class CNot: public CItemBase

{

Public :

       Virtual void draw(void);

}

假设有一个指针数组CArray array;里面有And, Or, Not的三个实例,则可以这样画图:

CItemBase *p

Int cnt = array,GetCount();

For(int i=0; i<cnt; i++)

{

       P = array.GetAt(i);

       p->draw(); /*p 会在运行时自动找到对应的画图函数*/

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值