2011-12-29 49 views
-1

我正在學習C++。在內存圖中需要幫助

我想有一個很好的內存視圖,就像下面的代碼運行時引擎蓋下的內容一樣。

// dynamic_cast 
    #include <iostream> 
    #include <exception> 
    using namespace std; 

    class CBase { virtual void dummy() {} }; 
    class CDerived: public CBase { int a; }; 

    int main() { 
    try { 
    CBase * pba = new CDerived; 
    CBase * pbb = new CBase; 
    CDerived * pd; 

    pd = dynamic_cast<CDerived*>(pba); 
    if (pd==0) cout << "Null pointer on first type-cast" << endl; 

    pd = dynamic_cast<CDerived*>(pbb); 
    if (pd==0) cout << "Null pointer on second type-cast" << endl; 

    } catch (exception& e) {cout << "Exception: " << e.what();} 
    system("PAUSE"); 
    return 0; 
    } 

任何人都可以請幫我..?

+1

哪一部分是不確定的? – John 2011-12-29 15:53:04

+1

我不確定這樣的圖表會是什麼樣子。你能提供一個例子嗎? – cdhowie 2011-12-29 15:54:14

+0

好吧,如果你可以畫出前4行..沒關係我 – user882196 2011-12-29 15:54:25

回答

0

pd = dynamic_cast<CDerived*>(pba);後,情況是這樣的:

pba ---> [CDerived] 
     ^
pd -------' 

pbb ---> [CBase] 

即,pbapd指向同一個對象。但是,它們的輸入方式不同。

pd = dynamic_cast<CDerived*>(pbb);後,pd0(空),因爲投無效:

pba ---> [CDerived] 

pd ----> (null) 

pbb ---> [CBase] 
1

我不太清楚你真正的問題是什麼,但我假設它是如何的dynamic_cast <> ()的作品。從實際的角度來看,它在內部如何實施並不重要,特別是對於不同的系統而言,實施方式不同。有Stanley Lippman的書(「C++對象模型內部」),這本書現在有點過時,但仍然很好地描述了這些細節以形成一幅心理圖像。需要注意的重要一點是,使用dynamic_cast <>()不僅僅是查看具有不同類型的對象並可能進行一些較小的調整,但可能涉及在類似於繼承樹的內部表示中搜索內容。

這就是說,將dynamic_cast(PBA)大致是這樣的:

  1. 獲取一個指向內部類型信息(通常稱爲「虛函數指針表」或「VTBL」雖然當代實現別使用vanilla虛擬函數指針表)來標識類型。爲了這個工作,dyanmic_cast的參數的靜態類型(在本例中爲「CBase」)需要至少有一個虛函數。
  2. 此對象中的類型信息可能與目標類型(例如您的示例中的情況)一致,在這種情況下系統會對指針(在某些情況下需要涉及多重繼承的情況下需要進行必要的調整)和返回相應的指針。否則,即如果目標類型可以是對象的動態類型的基類,則系統嘗試在動態類型的基類中找到目標類型。在單一繼承的情況下,這相當簡單,但如果涉及多重繼承,則可能涉及很多搜索。

也就是說,使用dynamic_cast <>()會頻繁地將性能問題引入到您的程序中。但是,在需要的地方不使用它會造成程序崩潰的可能性。一般來說,使用dynamic_cast <>()的需求相對較少。如果你發現自己使用dynamic_cast <>(),你的設計幾乎肯定是有缺陷的。