我有一组类,它们描述了一组可以容纳东西并对它们做事的逻辑框。我有
struct IBox // all boxes do these
{
....
}
struct IBoxCanDoX // the power to do X
{
void x();
}
struct IBoxCanDoY // the power to do Y
{
void y();
}
我想知道对于这些类的客户来说,处理这些可选功能的“最好”或者可能只是“最喜欢”的习语是什么
一种)
if(typeid(box) == typeid(IBoxCanDoX))
{
IBoxCanDoX *ix = static_cast<IBoxCanDoX*>(box);
ix->x();
}
b)
IBoxCanDoX *ix = dynamic_cast<IBoxCanDoX*>(box);
if(ix)
{
ix->x();
}
C)
if(box->canDoX())
{
IBoxCanDoX *ix = static_cast<IBoxCanDoX*>(box);
ix->x();
}
d)现在不同的类结构
struct IBox
{
void x();
void y();
}
...
box->x(); /// ignored by implementations that dont do x
e) 相同,除了
box->x() // 'not implemented' exception thrown
f) 显式测试功能
if(box->canDoX())
{
box->x();
}
我相信还有其他人。
编辑:
只是为了使用例更清晰
我通过交互式 ui 将这些东西暴露给最终用户。他们可以输入“make box do X”。我需要知道box是否可以做x。或者我需要禁用 'make current box do X' 命令
EDIT2:感谢所有回答者
正如诺亚·罗伯茨(Noah Roberts)指出的那样(a)不起作用(解释了我的一些问题!)。我最终做了(b)和一个轻微的变体
template<class T>
T* GetCurrentBox()
{
if (!current_box)
throw "current box not set";
T* ret = dynamic_cast<T*>(current_box);
if(!ret)
throw "current box doesnt support requested operation";
return ret;
}
...
IBoxCanDoX *ix = GetCurrentBox<IBoxCanDoX>();
ix->x();
并让 UI 管道很好地处理异常(我并没有真正抛出裸字符串)。
我也打算探索访客