问题描述
#include <iostream>
using std::cout;
using std::endl;
class A {
public:
virtual void talk() { cout << "person talking" << endl;}
};
class B : public A {
public:
void work() { cout << "employee working" << endl; }
};
int main() {
A* pA = new B();
if (typeid(*pA) == typeid(B))
cout << "yes" << endl; // this is printed
else
cout << "no" << endl;
}
#include <iostream>
using std::cout;
using std::endl;
class A {
public:
void talk() { cout << "person talking" << endl;}
};
class B : public A {
public:
void work() { cout << "employee working" << endl; }
};
int main() {
A* pA = new B();
if (typeid(*pA) == typeid(B))
cout << "yes" << endl;
else
cout << "no" << endl; // this is printed
}
为什么会这样?
为什么方法的虚拟性会影响对象的类型?
编辑:
为了使事情更加混乱,这可以正常工作:
((B*)(pA))->work(); // works fine,prints "employee working"
那么* pA为什么仅被视为A类对象(没有虚拟关键字时)却仍然可以调用child的work()方法?
解决方法
typeid
的工作方式。没有虚拟成员的类是非多态类型,并且不包含运行时类型信息。因此,无法在运行时确定其类型。
请参见[expr.typeid]/p2:
将
typeid
应用于类型为多态类类型的glvalue表达式时,结果引用的是std::type_info
对象,该对象表示派生程度最高的对象的类型(即动态类型) glvalue所指向的位置。
将
typeid
应用于多态类类型的glvalue以外的表达式时,结果引用表示该表达式静态类型的std::type_info
对象。
静态类型表示仅在编译时确定类型(对于A*
,它就是A
)。