众所周知,下面的代码段会打印Derived
或类似内容。
#include<iostream>
#include<typeinfo>
class Base { public: virtual ~Base(){} };
class Derived : public Base{};
int main()
{
Derived d;
Base& b = d;
std::cout << typeid(b).name() << '\n';
}
但是我想从标准(N4140)第5.2.8 / 2段开始理解如何得出结论。例如,b
肯定是一个glvalue,但Base&
类型与Base
不同,所以我不能说b
是多态的。我错过了什么?
答案 0 :(得分:5)
来自[expr]
如果表达式最初具有“对T的引用”类型(8.3.2,8.5.3),则类型在之前调整为T 进一步的分析。表达式指定由引用表示的对象或函数,以及 表达式是左值或左值,具体取决于表达式。
表达式b
最初的类型为“Base
的引用”,因此类型调整为Base
。它是一个左值,是一个glvalue。
来自[class.virtual]:
声明或继承虚函数的类称为多态类。
Base
声明了一个虚函数,因此它是一个多态类。
来自[expr.typeid]:
当
typeid
应用于类型为多态类类型(10.3)的glvalue表达式时,结果引用 到表示最派生对象(1.8)类型的std::type_info
对象(即动态 glvalue引用的类型。
基于以上所述,我们满足初始条件(表达式是glvalue,其类型是多态类类型),因此我们选择b
引用的最派生对象。那将是d
,其类型为Derived
。
如果b
是Base
而不是Base&
,那么派生得最多的对象本身就是b
。