通过基类指针传递参数时检查子类型

时间:2016-12-20 15:53:18

标签: c++

我有一个基础B及其2个派生(D1D2)类看起来像这样

struct B
{
   virtual B* DoSomething()=0;
};

struct D1:public B
{
   B* DoSomething()
   {
      // D1 does something
      return pD1;
   }
};

struct D2:public B
{
   B* DoSomething()
   {
     // D2 does something
     return pD2;
   }
};

现在我有了一个功能

void Init(B*pB)
{
   if(pB is D1)
   {
      D1* pD1=down_cast(pB);
      pD1->MethodD1();
   }
   else if(pB is D2)
   {
      D2* pD2=down_cast(pB);
      pD2->MethodD2();
   }
   else
   {
      //do something else
   }
}

我不想像这样检查Init()方法中的类型,但不知道我还能做什么。

2 个答案:

答案 0 :(得分:1)

以下是您的Init()方法,而不是伪代码:

void Init(B*pB)
{
   if(D1 *pD1 = dynamic_cast<D1*>(pB))
   {
      pD1->MethodD1();
   }
   else if(D2 *pD2 = dynamic_cast<D2*>(pB))
   {
      pD2->MethodD2();
   }
   else
   {
      //do something else
   }
}

正如您所看到的那样,如果派生类的类型不是您要投射的类型,那么您可以看到dynamic_cast返回nullptr

你也可以使用引用来做到这一点,在这种情况下,如果类型不是你正在构建的类型,dynamic_cast会返回一个异常,因此,由于异常处理不是免费的,所以最好使用指针进行动态强制转换。 另请注意,这是运行时检查,而不是编译时检查。

答案 1 :(得分:1)

你真的应该这样做

at = [100, 222, 333]

并在您的主要代码中

struct B
{
   virtual void Init();
   virtual B* DoSomething()=0;
};

struct D1:public B
{
   B* DoSomething()
   {
      // D1 does something
      return pD1;
   }
   void Init()
   {
      MethodD1();
   }

};


struct D2:public B
{
   B* DoSomething()
   {
      // D2 does something
      return pD2;
   }
   void Init()
   {
      MethodD2();
   }

};

这就是封装,继承,虚拟方法等的全部意义。