C++ 向上投射和向下投射对象时出现无效的初始化错误

C++ 向上投射和向下投射对象时出现无效的初始化错误,c++,class,downcast,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::c

考虑以下代码:

#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;
}
#包括
#包括
班级家长
{
公众:
虚拟void foo()常量{};
};
类Child_A:公共虚拟父级
{
};
无效下行(const Child_A&aa)
{
}
无效向上投射(常量父项和pp)
{

std::coutDowncast不能隐式完成。要更正它,您可以通过
static\u cast
dynamic\u cast
使强制转换显式进行。但是,由于
Parent
Child\u a
的虚拟基础。只有
dynamic\u cast
适用于此处。因此,要使代码正确,您可以更改
Downcast(pp);
to
downcast(dynamic_cast(pp));
void upcast(const Parent&pp)
中,
pp
的静态类型是
Parent
,但它的动态类型(real type)is
Child\u A
typeid
查询动态类型,这就是为什么打印
7Child\u A
的原因。

不能隐式进行向下转换。要更正它,可以通过
静态转换
动态转换
使转换显式化。但是,因为
父项
子项的虚拟基础。只有
dynamic_cast
在这里适用。因此,为了使代码正确,您可以将
downcast(pp);
更改为
downcast(dynamic_cast(pp));
。在
void upcast(const Parent&pp)
中,
pp
的静态类型是
Parent
,但它的动态类型(real type)is
Child\u A
typeid
查询动态类型,这就是为什么打印
7Child\u A
的原因。

您有一个基于
向上转换(aa)的隐式派生基转换
line.
pp
指的是
aa
中包含的基类子对象。没有隐式的基类到派生类的转换。
static\u cast
可用于执行向下转换,但由于
Parent
是一个虚拟基类,因此您必须改用
dynamic\u cast

if (Child_A* c = dynamic_cast<Child_A const*>(&pp)) {
    downcast(*c);
}
if(Child_A*c=dynamic_cast(&pp)){
下行(*c);
}
typeid(pp).name()
返回子类输出字符串,因为当应用于多态类型的对象(
Parent
具有虚拟方法,因此是多态的)时,结果是派生最多的类:

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


请注意,
pp
的实际静态类型是
父常量&

您有一个基于
向上转换(aa)的隐式派生到基转换
line.
pp
指的是
aa
中包含的基类子对象。没有隐式的基类到派生类的转换。
static\u cast
可用于执行向下转换,但由于
Parent
是一个虚拟基类,因此您必须改用
dynamic\u cast

if (Child_A* c = dynamic_cast<Child_A const*>(&pp)) {
    downcast(*c);
}
if(Child_A*c=dynamic_cast(&pp)){
下行(*c);
}
typeid(pp).name()
返回子类输出字符串,因为当应用于多态类型的对象(
Parent
具有虚拟方法,因此是多态的)时,结果是派生最多的类:

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


请注意,
pp
的实际静态类型是
Parent const&

typeid
是一个运行时操作符。只要
upcast
,编译器就不知道
pp
实际上是一个
子对象。
pp
是对
Parent
的引用。您不能将对
Parent
的引用传递给一个函数,它需要一个对
Child\u a
的引用(此代码中没有强制转换,只有隐式转换)这个问题过于复杂,可以简化为一个小得多的具有代表性的例子。
typeid
是一个运行时操作符。只要
upcast
,编译器就不知道
pp
实际上是一个
子对象。
pp
是对
父对象的引用。您不能传递对
父级
到一个函数,该函数需要引用子级
(此代码中没有强制转换,只有隐式转换。)这个问题太复杂了,可以简化为一个小得多的、有代表性的例子。
static\u cast
在这里不起作用。
Parent
Child\u a
@Lingxi的虚拟基础。因此,他将来必须使用
dynamic\u cast
返回。
c
的类型应该是
Child\at*
。我错了。
静态演员
在这里不起作用。
父演员
子演员
@Lingxi的虚拟基地。所以他将来必须使用
动态演员
c
的类型应该是
子演员*
。我错了。