预期的等价性:数据表达式和类型表达式的typeid

时间:2016-08-23 14:37:17

标签: c++ polymorphism typeid equivalence

我有从基类A派生的多态类:

class A {
public:
    virtual void fV() { }
};

class B : public A {
public:
    void mB() { }
};

class C : public A {
public:
    void mC() { }
};

我现在想迭代指向这些对象的数组并检查类型等价:

A *array[4] = { new B, new C, new C, new B };
for(int i = 0; i < 4; ++i) {
    cout << i + 1 << ". " ;
    (typeid(array[i]) == typeid(A)) ? cout << 1 << ' ': cout << 0 << ' ';
    (typeid(*array[i]) == typeid(B)) ? cout << 1 << ' ': cout << 0 << ' ';
    (typeid(*array[i]) == typeid(C)) ? cout << 1 << ' ': cout << 0 << ' ';
    cout << endl;
}

结果是:

1. 0 1 0 
2. 0 0 1 
3. 0 0 1 
4. 0 1 0 

我期望第一个条件中的类型等价,但结果我获得了失败的比较(第一列中的0 0 0 0)。第二和第三个条件的结果如我所料。

第一个条件有什么问题?

1 个答案:

答案 0 :(得分:0)

您的数组定义为A* array[4]。因此array[i]的类型将为A*

因此,对于第二列(索引后的第一列):

  • typeid(array[i]) == typeid(A)将始终为假(即第二列为0)
  • typeid(array[i]) == typeid(A*)永远是真的(即第二列中的1)
  • 如果您的阵列中有新的A项,则
  • typeid(*array[i]) == typeid(A)可能为真。

Online demo对于第三种情况,用A对象替换一个派生对象。

警告: 您检查的类型等效是严格类型等价。这只适用于完全匹配。这意味着对于第二列,对于从B派生的对象,测试将失败。也许这就是您正在寻找的并且很好。但是,如果您只想检查是否要调用mB()mC(),这会严重限制您的多态设计的可扩展性。或者,您可以考虑使用dynamic_cast<>并检查它是否返回nullptr