虚拟成员函数更改 typeid 的结果 - 为什么?
Virtual member function changes result of typeid - why?
此代码运行良好并打印“yes”:
#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;
}
但如果我删除 virtual 关键字,它将打印“no”
#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只被视为class一个对象(当没有virtual关键字时)却仍然可以调用child的work()方法?
这就是 typeid
的工作原理。没有虚拟成员的 class 是 non-polymorphic 类型 并且不携带 run-time 类型信息。因此无法在 运行 时间确定它的类型。
When typeid
is applied to a glvalue expression whose type is a polymorphic class type, the result refers to a std::type_info
object representing the type of the most derived object (that is, the dynamic type) to which the glvalue refers.
When typeid
is applied to an expression other than a glvalue of a polymorphic class type, the result refers to a std::type_info
object representing the static type of the expression.
静态类型 表示类型仅在 compile-time 处确定(对于 A*
因此是 A
)。
此代码运行良好并打印“yes”:
#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;
}
但如果我删除 virtual 关键字,它将打印“no”
#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只被视为class一个对象(当没有virtual关键字时)却仍然可以调用child的work()方法?
这就是 typeid
的工作原理。没有虚拟成员的 class 是 non-polymorphic 类型 并且不携带 run-time 类型信息。因此无法在 运行 时间确定它的类型。
When
typeid
is applied to a glvalue expression whose type is a polymorphic class type, the result refers to astd::type_info
object representing the type of the most derived object (that is, the dynamic type) to which the glvalue refers.
When
typeid
is applied to an expression other than a glvalue of a polymorphic class type, the result refers to astd::type_info
object representing the static type of the expression.
静态类型 表示类型仅在 compile-time 处确定(对于 A*
因此是 A
)。