我有一个基础B
及其2个派生(D1
,D2
)类看起来像这样
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()
方法中的类型,但不知道我还能做什么。
答案 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();
}
};
这就是封装,继承,虚拟方法等的全部意义。