2015-04-04 93 views
1

該書The c++ programming language有關於dynamic_cast的部分,我不知道我的理解是否正確。dynamic_casting的對象混淆

dynamic_cast的目的是處理轉換的正確性無法由編譯器確定的情況。在這種情況下,dynamic_cast(p)查看p指向的對象(如果有的話)。如果該對象屬於類T或具有T類型的唯一基類,則dynamic_cast將返回一個類型爲T *的指針給該對象;否則,返回nullptr。如果p的值是nullptr,dynamic_cast(p)返回nullptr。請注意,轉換必須是唯一標識的對象。可以構造轉換失敗並返回nullptr的示例,因爲p指向的對象具有多個表示類型爲T的基類的子對象。

「是否可以構造轉換失敗的示例,返回nullptr是因爲對象指向 to p有多個子對象表示類型T的基類「意思是這樣的?

class a { 
public: 
    a() { } 
}; 

class b : public a { 
public: 
    b() { } 
}; 

class z : public a, public b { 
public: 
    z() { } 
}; 

void f(z* p) { 
    a* x = dynamic_cast<a*>(p); // ambiguous 
} 

而另外一個,這是從書採取:

class Component : public virtual Storable { /* ... */ }; 
class Receiver : public Component { /* ... */ }; 
class Transmitter : public Component { /* ... */ }; 
class Radio : public Receiver, public Transmitter { /* ... */ }; 
爲指針的無線電對象的模糊性不是一般的檢測在編譯時。 這種運行時歧義檢測僅適用於虛擬基地。對於普通的基礎,當向下轉換時(即向派生類;§22.2),總是有一個給定演員(或無)的唯一子對象。虛擬基地的等同含糊性發生在上傳(即向基地)時,但這種歧義在編譯時被捕獲。

我完全不明白這一點。這是什麼意思「對於普通的基礎,總是有一個特定的演員的獨特的子對象」?我知道如果基礎不是虛擬的,將爲每個從它派生的類創建一個子對象。但就演員而言,我剛剛在上面的例子中造成了一個模棱兩可的錯誤。而「上傳時發生虛擬基地的等效歧義」,這是什麼意思?虛擬基地可能模棱兩可嗎?任何人都可以解釋清楚嗎?

+0

除非您使用'virtual'基礎,否則給定'a'只有一個孩子'z'。 – Yakk 2015-04-04 14:33:49

+0

@Yakk 你指的是什麼? – morbidCode 2015-04-04 14:53:39

+0

你的課a和z以上? – Yakk 2015-04-04 14:57:35

回答

1

對於普通[非虛擬]鹼基,總是有向下轉換時(即,向着一個派生類的給定流延(或無)的唯一子對象;§22.2

這是因爲非虛擬繼承會創建派生類的嚴格層次結構,而分支不會再次聚集在一起。對象必須是派生類T中的某個派生類,該類派生於該類樹的葉節點處。不能再次遇到T,因爲一個類不能從它自身繼承,因此,動態下降到T,你將最終得到對象的派生類。對於(或每個)繼承鏈中的任何類都是類似的。

+0

那麼這句話呢?「上傳時虛擬基地的等效歧義發生,但在編譯時捕獲到這種歧義。」這是什麼意思? – morbidCode 2015-04-04 14:50:36

+0

這意味着如果您正在向上注視,從'D&'到'B&',並且有兩個或多個類型爲'B'的基類,那麼在編譯時就知道了。在相反的方向上,從'B&'到'D&',在編譯時不知道是否有0,1個或更多'D'子對象,因爲這取決於當前綁定的對象的最派生類型以供參考。 'dynamic_cast'必須根據編譯器發出的類型信息計算出來,並且要麼成功,要麼給你一個空指針,或者爲了引用而拋出一個異常。 – 2015-04-04 16:06:04