预期等价:数据表达式和类型表达式的typeid
Expected equivalence: typeid of data expression and type expression
我有从基数 class 派生的多态性 class 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)。第二个和第三个条件的结果和我预想的一样
第一个条件有什么问题?
您的数组定义为 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<>
并检查它是否 returns nullptr 或 not
我有从基数 class 派生的多态性 class 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)。第二个和第三个条件的结果和我预想的一样
第一个条件有什么问题?
您的数组定义为 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<>
并检查它是否 returns nullptr 或 not