您的位置:首页 > 编程语言 > C语言/C++

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

2013-12-08 12:05 288 查看
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、能力查询只是偶尔需要。

除非身陷找不到其他合理方式的困境,否则最好避免对一个对象的能力进行运行期查询。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: