2013-11-20 76 views
5
void foo(MyClass* myClass) 
{ 
    BaseClass* pBaseClass = dynamic_cast<BaseClass*>(myClass); 
    delete myClass; // <-------------- Does this affects on pBaseClass ? 
} 

一般如何dynamic_cast實際工作? (它是否像複製構造函數一樣工作?)dynamic_casting後刪除指針是否安全?

+0

如果你要一個副本(並假設BaseClass的實際上是一個基類)一個體面的解釋,然後'BaseClass的BC = *類;' – john

+0

如果'BaseClass'是實際上是* base *類,那麼'dynamic_cast'的意義是什麼?或者有關於此事的演員? – AnT

回答

5

(請注意,class不是有效的變量名稱,因爲它是一個關鍵字,所以我將其稱爲c)。

dynamic_casting後刪除指針是否安全?

是的;但要注意,刪除指向的對象後,兩個指針都是無效的。之後您不能使用任何一個指針值。

一般dynamic_cast實際上是如何工作的?

它將指針或對類類型的引用轉換爲指向不同類類型的指針或引用,並使用運行時檢查轉換是否有效。在這種情況下,如果BaseClass與該對象的動態類型相同或基類,則轉換將會成功(提供有效指針)。否則將失敗(給出空指針)。

如果您將*c轉換爲引用類型,那麼失敗將導致異常(std::bad_cast),因爲不存在空引用之類的事情。

它是否像複製構造函數一樣工作?

編號構造函數用於複製對象。這不會複製它,只是改變指向它的指針的類型。副本看起來像

BaseClass bc = *c; 

注意的bc類型是BaseClass,不是c類型(這是從推測BaseClass派生的類);這被稱爲「切片」,因爲該對象的派生部分被「切掉」並且不被複制。

7

不,不是安全。 dynamic_cast只是一種類型轉換 - 原始指針和轉換指針都指向同一個對象。

被轉換的指針可能會指向一個略微不同的地址(如果涉及多重繼承),但它仍然指向(同一個對象) - 不發生對象複製。

編輯:我的意思是在這個意義上「不安全」「你delete myClass後,pBaseClass是一個懸擺指針。」不過,它仍然是合法的代碼。只是相當危險。

+0

爲什麼不呢? 'dynamic_cast'要麼成功,那麼就存在一個繼承關係,它使得cast和calling'delete'合法(正確的析構函數將被虛擬調度)。或'dynamic_cast'返回'nullptr',這也是安全的。該標準將'delete nullptr'定義爲no-op。 – Damon

+0

@Damon增加了一個解釋;我有一個強烈的印象,那就是OP之後的「安全」的意義。 – Angew

+1

好的,我不認爲有人可能會嘗試刪除後仍然使用原始指針。有效點:-) – Damon