2012-08-07 81 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;