您好 我已经开始研究一些预先存在的代码,它由一个元素树组成,每个元素都是一个通用元素的后代,它具有一个类型数据成员。
搜索功能返回一个通用元素,然后用户检查类型,并可以向下转换为特定类型以访问其特定信息。
此代码适用于手机,因此使用大量dynamic_cast可能效率低下。
代码是新的,不是一成不变的,所以可以改进(我没有写它,我刚加入公司并正在研究它,所以不想完全撕掉它。)< / p>
未来良好的设计/使用模式有哪些选择? (它的c ++但使用类型检查和原始c转换(以避免dynamic_casts的开销)似乎有点过时了。
例如,在基类中添加CastToXXX()类型函数是否有任何优势?
派生类的类型很可能是固定的。
答案 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类遍历树,然后您可以在树中的任何类型上操作,而不需要任何指针强制转换。
希望这有帮助。
干杯