是否有一个像dynamic_cast的体面替代品

时间:2012-02-15 19:56:14

标签: c++

我正在开发一个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();
   }

}

4 个答案:

答案 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();
}