在c ++中确定对象类型

时间:2017-09-15 12:55:18

标签: c++ oop types casting type-conversion

假设我有两个类映射两个具有相同接口的对象

,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 ++中检查子对象类型的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

有几种方法可以做到这一点。

typeiddynamic_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!";

来自:cppreference: dynamic cast

  

如果强制转换成功,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; }
}