我正在开发一个c ++项目,目前面临设计问题。如果有人能给我一些建议,我将不胜感激。基本上,我有一个基类Base和一个子类Derived如下。 Class Derived可以做类Base不能做的事情。
class Base
{
public:
virtual bool IsCapableOfDoingA() {return false;}
}
class Derived: public Base
{
public:
bool IsCapableOfDoingA() {return true;}
void DoA();
}
在另一个我有类型Base的指针的地方。
void functionA(Base *pBase)
{
if (pBase && pBase->IsCapableOfDoingA())
{
Derived *pDerived = static_cast<Derived*>(pBase);
pDerived->DoA();
}
}
答案 0 :(得分:4)
通常的方法是将函数添加到基类。
virtual void DoA() { throw std::runtime_error("Not implemented"); }
答案 1 :(得分:2)
在您的设计中,DoA
是否可以返回某种成功代码?您可以将IsCapableOfDoingA
替换为DoA
本身,并使Base版本只返回false(或其他合适的错误代码)。能够执行A
的子对象可以通过适当的实现覆盖此函数。
你是对的,dynamic_cast
通常是一种设计气味。通过更多的背景,我们可以提供更好的答案。我的第一个想法是确保Derived
IS-A Base
,如果您要多态地询问Base
s他们可能无法做的事情。
答案 2 :(得分:1)
dynamic_cast将返回NULL(假设基类定义了至少一个虚方法 - 通常至少应该使基类的析构函数为虚拟)。所以你可以使用以下习语:
void functionA(Base *pBase)
{
if (Derived *pDerived = dynamic_cast<Derived*>(pBase)) {
pDerived->DoA();
}
}
如果pBase没有Derived类型,那么pDerived将为0(false),因此将跳过if语句的主体。
答案 3 :(得分:0)
这是另一个想法。您可以将增强功能拆分为一个接口,并有一个返回接口指针的方法。
class InterfaceA
{
public:
virtual ~InterfaceA() {}
virtual void DoA() = 0;
};
class Base
{
public:
virtual InterfaceA* GetAInterface() {return NULL;}
};
class Derived: public Base, InterfaceA
{
public:
InterfaceA* GetAInterface() {return this;}
void DoA();
};
void functionA(Base *pBase)
{
InterfaceA* pA = pBase ? pBase->GetAInterface() : NULL;
if (pA)
pA->DoA();
}