C++必知必会之(27)能力查询

1、在大多数情况下,当一个对象出现并开始工作的时候,它就能够执行我们需要它做的事情,因为它的能力在其接口中已经被明确的通告了。在这些情形下,不需要询问该对象是否胜任我们要它执行的工作,只管叫它去做就行了:

class Shape {

     public:

         virtual ~Shape( );

         virtual void draw( ) const = 0;

         //....

};

//....

Shape *s = getSomeShape( );   //获得一个Shape,并且叫它去做...

s->draw( );       //干活


即使不知道所面对的形状的精确类型,我们也知道该对象”是一个“Shape,因此它可以绘制自身。这很高效且简单。

有时一个对象具备出来准备工作的能力,但它的能力并非那么显而易见。

例如,我们需要一些可以滚动的形状:

class Rollable {

       public:

            virtual ~Rollable( );

            virtual  void roll( ) = 0;

};

像Rollable这样的类通常称为“接口类”。因为它只指定了接口,如同java接口一样。

通常来说,这样的类没有非静态成员数据成员,没有声明构造函数。

一个虚析构函数和一个(或一组)纯虚函数指明了一个Rollable对象能够做什么。


2、不幸的是,我们偶尔会不知道一个对象是否具有所需能力。在这种情况下,我们被迫执行一个能力查询。

在c++中能力查询是通过对“不相关”的类型进行dynamic_cast转换而表达的。

Shape *s = getSmoeShape( );

Rollable *roller = dynamic_cast<Rollable *> (s);


这种dynamic_cast用法通常称为“横向转型”。

因为它试图在一个类层次结构中执行横向转换,而不是向上或向下转换。

如果s实际指向的是一个Shape,那么dynamic_cast将会失败(结果产生一个空指针),从而知道s所指向的Shape不是Rollable。如果s指向的是一个Circle或从Rollable派送下来的其他Shape,那么转型会成功,从而得知可以滚动这个形状。


Shape *s = getSomeShape( );

if( Rollable *roller = dynamic_cast<Rollable *> (s) )

       roller->roll( );


3、能力查询只是偶尔需要。

除非身陷找不到其他合理方式的困境,否则最好避免对一个对象的能力进行运行期查询。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值