C ++继承向下转换(C++ inheritance downcasting)

2019-06-26 20:59发布

我有我的基类,如下所示:

class point    //concrete class
{
 ...    //implementation
}

class subpoint : public point  //concrete class
{
...     //implementation
}

如何从一个点对象转换为下点对象? 我已经尝试了所有三个如下:

point a;
subpoint* b = dynamic_cast<subpoint*>(&a);
subpoint* b = (subpoint*)a;
subpoint b = (subpoint)a;

什么是错的,这些类型转换?

Answer 1:

如何从一个点对象转换为下点对象?

你不能; 除非任何point具有转换操作,或subpoint具有转换构造,在这种情况下的对象类型可以与不需要的铸造进行转换。

你可以从铸point 引用 (或指针)到subpoint 引用 (或指针),如果称为对象是类型的实际上subpoint

subpoint s;

point & a = s;
subpoint & b1 = static_cast<subpoint&>(a);
subpoint & b2 = dynamic_cast<subpoint&>(a);

第一( static_cast )更危险的; 没有检查,转换是有效的,因此,如果a不指subpoint ,然后用b1将有不确定的行为。

第二( dynamic_cast )是安全的,但如果只会工作point是多态的(也就是说,如果它有一个虚函数)。 如果a指的是不兼容的类型的对象,那么它会抛出异常。



Answer 2:

对于第一个例子, dynamic_cast如果有在基类的至少一个虚拟方法仅适用。 如果对象实际上不是你想投的类型,它会导致NULL。

对于第二个例子,你需要&a而不是a ,但一旦你定,你会得到不确定的行为,因为对象类型是错误的。

第三个例子需要一个operator subpoint()在方法point做了转化率,同时创建一个副本。



Answer 3:

动态铸件的目的在于“在运行时检查对象是否是特定类型的层次结构中的的”。 所以,现在让我们来看看你有什么:

  1. 你有一个点对象。 没有一个下点。
  2. 你问一个动态转换,如果对象是下点。 不是。
  3. 因为它不是一个下点时,将dynamic_cast失败 - 它告诉你,对象不是你想将它转换为类型的方式。

与此相反,这会工作:

subpoint c;
point *a = &c;
subpoint* b = dynamic_cast<subpoint*>(&a);
subpoint* b = (subpoint*)a;


Answer 4:

总体来说,这是行不通的,因为point是不是一个subpoint ; 只有正好相反。 不过,也有其他一些问题。

为了:


subpoint* b = dynamic_cast<subpoint*>(&a);

dynamic_cast仅适用于多态类型,即至少声明一个虚函数的类型。 我的猜测是, point没有虚函数,这意味着它不能被使用dynamic_cast


subpoint* b = (subpoint*)a;

对于这个投地工作, point需要声明一个转换操作符来subpoint * ,如point::operator subpoint *()


subpoint b = (subpoint)a;

对于这个投地工作,一点需要声明一个转换操作符来subpoint subpoint需要有一个构造函数参数从可转换point



Answer 5:

什么是错的,这些类型转换?

你试图做他们的事实。 一个point是不是subpoint ,我会感到惊讶,如果它的工作。



Answer 6:

a不能被制作成subpoint 。 该实现是不存在的。



文章来源: C++ inheritance downcasting