向上转换和向下转换对象时出现无效的初始化错误

Invalid initialization error while upcasting and downcasting an object

考虑以下代码:

#include <typeinfo>
#include<iostream>

class Parent
{
public:
   virtual void foo() const{};
};

class Child_A: public virtual Parent
{
};

void downcast( const Child_A& aa)
{
}

void upcast( const Parent& pp )
{
  std::cout<< typeid( pp ).name() << std::endl;
  downcast(pp); // line 21: This is the problematic line!
}


int main()
{
  Child_A aa;
  upcast(aa);
  return 0;
}

我遇到一个编译错误:

initialization.cpp:21:14:错误:从类型 'const Parent'[=14 的表达式对类型 'const Child_A&' 的引用的初始化无效=]

沮丧(pp);

但是如果我编译没有第 27 行的代码,typeid( pp ).name() returns 7Child_A.

那么为什么会出现此错误?我该如何解决? pp 的真正类型是什么?

不能隐式进行向下转换。要更正它,您可以通过 static_castdynamic_cast 使转换显式。但是,由于 ParentChild_A 的虚拟基数。此处仅适用 dynamic_cast。因此,为了使您的代码正确,您可以将 downcast(pp); 更改为 downcast(dynamic_cast<const Child_A&>(pp));。在void upcast( const Parent& pp )中,pp的静态类型是Parent,但它的动态类型(真实类型)是Child_Atypeid 查询动态类型,这就是打印 7Child_A 的原因。

您在 upcast(aa) 行上有一个隐式的派生到基础的转换。 pp 指的是 aa 中包含的基础 class 子对象。没有隐式的基到派生转换。 static_cast 可用于执行向下转换,但由于 Parent 是一个虚拟基数,因此您必须使用 dynamic_cast 代替:

if (Child_A* c = dynamic_cast<Child_A const*>(&pp)) {
    downcast(*c);
}

typeid(pp).name() returns一个子class输出字符串,因为当应用于多态类型的对象时(Parent有一个虚拟方法所以它是多态的) ,结果最推导class:

When typeid is applied to a glvalue expression whose type is a polymorphic class type (10.3), the result refers to a std::type_info object representing the type of the most derived object (1.8) (that is, the dynamic type) to which the glvalue refers.

注意 pp 的实际静态类型是 Parent const&typeid isn't a very reliable way to get the type of an object.