多态指针的typeid是什么?

17

我不明白为什么指针不能是多态类型,因为我们可以使用指向派生类的基类指针来调用派生类的虚函数。这表明在运行时,系统可以确定指针是否是多态的,不是吗?

(这是多态类型的typeid的后续问题。)


基类指针不指向派生类,它们指向基类。这基本上使您的结论无效。 - user405725
指针根本不指向类。它们指向对象,这些对象可以是基类或派生类类型。我认为这就是OP的意思(尽管措辞确实不太理想)。 - jogojapan
如果指针被视为多态类型,会有什么不同?你能做些现在做不到的事情吗? - n. m.
@jogojapan:没问题,类的实例或对象都可以。指向基类的指针永远不会指向派生类。绝对不会。 - user405725
@VladLazarenko 我的意思是这样一种情况:struct A {}; struct B : A {}; int main() { A* ap = new B; } 在这里,ap 被声明为指向基类的指针,但实际上它指向了派生类的对象。 - jogojapan
显示剩余5条评论
2个回答

13
实际上,标准(C++11)在描述typeid的行为时使用术语“多态类类型”而不是“多态类型”:
首先,它描述了当应用于类类型的 lvalue 时会发生什么情况(即它所做的事情的情况):
(§5.2.8/2)当typeid应用于具有多态类类型(10.3)的 glvalue 表达式时,结果是指代表示最派生对象(1.8)的std::type_info 对象(即动态类型),该 glvalue 指的是。[...]
但是,当您将其应用于指针(即不是类类型的 lvalue)时,适用以下规则:
(§5.2.8/3)当typeid应用于多态类类型之外的表达式时,结果是指代表达式的静态类型的std::type_info 对象。[...]
它说你得到静态(而不是动态)类型,也就是说,你得到指针的声明类型,而不是它实际指向的对象类型。
因此,是的,指针具有您描述的多态特性,但是不适用于typeid的结果。
(实际上,它们的所有多态特性(包括特别是多态成员函数调用)只有在涉及某种显式解引用(使用*或使用->)时才会表现出来。因此,你应该真正说指针本身不是多态的;只有在解引用它们时得到的对象才是。)

9
你的问题存在术语使用不正确的情况。C++语言在指针本身和这些指针所指向的对象之间有非常明确的区别。指针类型本身不具有多态性,指针本身没有任何多态性可言。真正可能具有多态性的是指针所指向的类型。当指针指向一个多态类型时,我们通常(非正式地)称之为“多态指针”(只是简单地表示“指向多态类型的指针”)。但是对于像typeid这样的东西来说,它们看待事物非常正式。对于typeid来说,指针类型永远不会是多态的。
编译器在运行时不确定指针是否具有多态性,这种简单的区分总是在编译时立即得知。如果将指针声明为指向多态类型的指针,则将其称为“多态的”指针。多态类型是一个包含虚函数(直接或间接)的类类型。显然,具有多态性的属性是类型的纯粹编译时属性。
在这种情况下,唯一在运行时确定的事情是被指向的具体对象在给定时刻的类型。

2
使用准确的术语会让我意识到自己经常使用不恰当的词汇,因此为你加1分。 - jogojapan
谢谢你们两个。现在这一切都很有意义了。 :) - user2465355

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接