2012-08-07 79 views
11

我有我的基类,如下所示:C++继承向下转换

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; 

这些演员出了什么问题?

回答

22

如何从点对象转换为子对象?

你不能;除非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引用不兼容类型的对象,则会引发异常。

+0

将被铸造的对象实际上是类型的子点,它只是在一个点数组中。 – CodeKingPlusPlus 2012-08-08 13:00:52

0

a不能被制成subpoint。该实施不在那里。

0

这些演员出了什么问题?

你试图做的事实。 A point不是subpoint,如果它有效,我会感到惊讶。

1

总的来说,这是行不通的,因为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; 

对于这个投地工作,一点需要一个转换操作符申报subpointsubpoint需要有一个构造函数的参数可转换从point

2

对于第一个示例,dynamic_cast仅适用于基类中至少有一个虚拟方法。如果该对象实际上不是您想要投射的类型,则会导致NULL。

对于第二个例子,您需要&a而不是a,但是一旦您修复了这个问题,您将得到未定义的行为,因为对象类型是错误的。

第三个示例要求point中的operator subpoint()方法在创建副本时进行转换。

+1

@MooingDuck,界定 “将无法正常工作”?它应该返回一个NULL指针,这可能不是预期的结果,但它会编译并做一些有用的事情。 – 2012-08-07 22:56:35

+0

我一定误解了你的答案,现在对我来说很好。 – 2012-08-07 22:58:12

1

动态转换的目的是“在运行时检查对象在层次结构中是否属于某种类型”。所以现在让我们看看你有什么:

  1. 你有一个点对象。不是一个子点。
  2. 如果对象是一个子点,您正在问一个动态转换。不是。
  3. 因为它不是一个子点,所以dynamic_cast失败 - 它告诉你该对象不是你想要转换的类型。

相反,这会工作:

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