使用安全向下转换的类设计选项

时间:2011-03-21 18:05:41

标签: c++ oop

您好 我已经开始研究一些预先存在的代码,它由一个元素树组成,每个元素都是一个通用元素的后代,它具有一个类型数据成员。

搜索功能返回一个通用元素,然后用户检查类型,并可以向下转换为特定类型以访问其特定信息。

此代码适用于手机,因此使用大量dynamic_cast可能效率低下。

代码是新的,不是一成不变的,所以可以改进(我没有写它,我刚加入公司并正在研究它,所以不想完全撕掉它。)< / p>

未来良好的设计/使用模式有哪些选择? (它的c ++但使用类型检查和原始c转换(以避免dynamic_casts的开销)似乎有点过时了。

例如,在基类中添加CastToXXX()类型函数是否有任何优势?

派生类的类型很可能是固定的。

3 个答案:

答案 0 :(得分:2)

dynamic_cast并不那么慢,你很可能无法做得更好。在查看替代解决方案之前,说明并证明它是性能瓶颈。从来没有做过任何事情,因为你可能听到某个地方可能会很慢。

答案 1 :(得分:1)

如果不能选择dynamic_cast / RTTI,处理此类情况的一种简单方法是使用Visitor Pattern

基本上,您定义了一个基类,它定义了安全地为您进行转换的方法:

    // Forward declarations.
class CFoo;
class CBar;

class CommonBase
{
public:
    virtual CFoo* GetFoo( void ) { return NULL };
    virtual CBar* GetBar( void ) { return NULL };
};

class CFoo : public GenericBase, public CommonBase
{
    .
    .
public:
    CFoo* GetFoo( void ) { return this };
};

class CBar : public GenericBase, public CommonBase
{
    .
    .
public:
    CBar * GetBar( void ) { return this };
};

现在,给定一个指向CommonBase对象的指针,可以通过“visting”向下转发:

CommonBase *p;
CFoo pFoo = p->GetFoo();
if( pFoo )
{
    // Winner!
}

答案 2 :(得分:1)

让树结构中的基类具有纯虚拟的Visit()方法。

class CBase {
  virtual void Visit(CVisitor* visitor) const = 0;
};

让继承的类实现它:

class CFoo : public CBase {
  virtual void Visit(CVisitor* visitor) const {
    visitor->Accept(this);
  }
};

class CBar : public CBase {
  virtual void Visit(CVisitor* visitor) const {
    visitor->Accept(this);
  }
};

最后的魔力:

class CVisitor {
  void Accept(CFoo* foo) {
    // operate on CFoo*
  }
  void Accept(CBar* bar) {
    // operate on CBar*
  }
};

因此,您需要做的就是为新类型创建Accept和Visit方法,并使用CVisitor类遍历树,然后您可以在树中的任何类型上操作,而不需要任何指针强制转换。

希望这有帮助。

干杯