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

时间:2015-04-17 14:05:48

标签: c++ class downcast

请考虑以下代码:

#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:错误:类型&#39; const Child_A&amp;&#39;的引用无效初始化来自类型&#39; const Parent&#39;

的表达式

垂头丧气(PP);

但如果我在没有第27行的情况下编译代码,typeid( pp ).name()会返回7Child_A

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

2 个答案:

答案 0 :(得分:3)

Downcast无法隐式完成。要更正它,您可以通过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被打印的原因。

答案 1 :(得分:3)

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

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

typeid(pp).name()返回子类输出字符串,因为当应用于多态类型的对象(Parent具有虚方法,因此它是多态的)时,结果是派生类最多的类: / p>

  

typeid应用于类型为多态类类型(10.3)的glvalue表达式时,结果引用表示最派生对象类型的std::type_info对象(1.8)(是glvalue引用的动态类型。

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