向上转换和向下转换对象时出现无效的初始化错误
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_cast
或 dynamic_cast
使转换显式。但是,由于 Parent
是 Child_A
的虚拟基数。此处仅适用 dynamic_cast
。因此,为了使您的代码正确,您可以将 downcast(pp);
更改为 downcast(dynamic_cast<const Child_A&>(pp));
。在void upcast( const Parent& pp )
中,pp
的静态类型是Parent
,但它的动态类型(真实类型)是Child_A
。 typeid
查询动态类型,这就是打印 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.
考虑以下代码:
#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_cast
或 dynamic_cast
使转换显式。但是,由于 Parent
是 Child_A
的虚拟基数。此处仅适用 dynamic_cast
。因此,为了使您的代码正确,您可以将 downcast(pp);
更改为 downcast(dynamic_cast<const Child_A&>(pp));
。在void upcast( const Parent& pp )
中,pp
的静态类型是Parent
,但它的动态类型(真实类型)是Child_A
。 typeid
查询动态类型,这就是打印 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 astd::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.