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