假设我有两个类映射两个具有相同接口的对象
,a a,b
0,1.25,1424380449437
1,2.54,1425510731187
2,NaN,NaN
稍后,在代码中完成了类似的事情
class FirstChild : class Father
{
//some fields and methods useful for class A
}
class SecondChild : class Father
{
//some fields and methods useful for class B
}
现在,如果我想知道对象的Father* myInstance = new SecondChild();
,那么如果实例是FirstChild或SecondChild,我必须做一些操作,我就是这样做的:
type
这是正确的方法吗?
因为在if (typeid (myInstance) == typeid (FirstChild))
{
// do stuff
} else if (typeid (myInstance) == typeid (SecondChild))
{
// do other stuff
}
上的某个地方,我认为StackOverflow
不安全且添加虚拟功能更方便,例如,让我们说typeid
,并且,在FirstChild
getType
老实说,我不太喜欢这个解决方案,因为我们似乎绕过了面向对象编程中的多态性。
所以,你们,你觉得怎么样?在c ++中检查子对象类型的最佳方法是什么?
答案 0 :(得分:1)
有几种方法可以做到这一点。
typeid
和dynamic_cast<>
是“官方方式”。
FirstChild *fptr = dynamic_cast<FirstChild>(myInstance);
if (fptr) {
// do something
} else {
SecondChild *cptr = dynamic_cast<SecondChild>(myInstance);
if(cptr) {
// do something else, and so on...
}
}
但这不是最优雅的方式。
另一种等效方式是拥有“id类型”,如枚举或类似内容。
但正如许多人所说,如果你需要知道这种类型是什么,你可能会采取错误的方式。
一个明显的选择是让对象执行特定操作。假设您在activate()
函数中使用此代码。为什么不使用虚拟doAction()
?
class Father {
public:
virtual void doAction() = 0;
}
//...
myInstance->doAction();
使用不同的设计模式有不同的变化。但我想你明白了。
答案 1 :(得分:0)
执行此操作的一种简单方法是使用dynamic_cast
。例如:
Father *myInstance = new SecondChild();
SecondChild *casted = dynamic_cast<SecondChild*>(myInstance);
if (casted != nullptr)
std::cout << "myInstance is a SecondChild!";
else
std::cout << "myInstance is not a SecondChild!";
如果强制转换成功,dynamic_cast将返回new_type类型的值。如果强制转换失败并且new_type是指针类型,则返回该类型的空指针。如果转换失败并且new_type是引用类型,则抛出与std :: bad_cast类型的处理程序匹配的异常。
正如@Rob指出的那样,你可以使用虚函数让对象自己动作。
struct Father
{
virtual void process() = 0;
};
您可以使用虚函数来决定是否应该执行操作,而不是检查类型。
struct Father
{
virtual bool shouldProcess() { return false; }
};
struct SecondChild : Father
{
bool shouldProcess() override { return true; }
}