我不明白为什么指针不是多态类型,因为我们可以使用指向派生类的基类指针来调用派生类的虚函数。这表明在运行时,系统可以确定指针是否是多态的,不是吗?
2 回答
事实上,标准 (C++11)在描述以下行为时使用术语多态类类型,而不是多态类型typeid
:
首先,这里描述了当typeid
应用于类类型的左值时会发生什么(即,当它执行您期望的情况时):
(§5.2.8/2) 当
typeid
应用于类型为多态类类型 (10.3) 的泛左值表达式时,结果引用std::type_info
表示最派生对象 (1.8) 类型的对象(即动态类型) 泛指值所指的。[...]
但是当你将它应用到一个指针(即不是一个类类型的左值)时,以下规则适用:
(§5.2.8/3) 当
typeid
应用于除多态类类型的泛左值以外的表达式时,结果是指std::type_info
表示表达式的静态类型的对象。[...]
它说你得到了静态(不是动态)类型,即你得到了指针的声明类型,而不是它实际指向的对象的类型。
所以,是的,指针具有您所描述的多态特征,但对于typeid
.
(事实上,它们的所有多态特征(尤其包括多态成员函数调用)只有在涉及某种显式取消引用时才会表现出来,无论是 using*
还是 using ->
。所以你真的应该说指针本身不是多态的;只有当你取消引用它们时你得到的对象才是。)
您的问题因术语使用不正确而受到影响。C++ 语言在指针本身和这些指针指向的对象之间做出了非常明确的区分。指针类型不是多态的。指针本身没有任何多态性。真正可以多态的是指针指向的类型。当指针指向多态类型时,我们通常 [非正式地] 将其称为多态指针(就像“指向多态类型的指针”的简写)。但是当涉及到类似的事情时typeid
,他们会非常正式地看待事情。因为typeid
指针类型永远不是多态的。
并且编译器不会在运行时确定指针是否是多态的。这种简单的区别总是在编译时立即知道。同样,如果将指针声明为指向多态类型的指针,则将其称为多态指针。多态类型是包含虚函数(直接或间接)的类类型。显然,多态的属性是一个类型的纯编译时属性。
在这种情况下,唯一在运行时确定的是指向对象在给定时刻具有哪种特定类型。