2012-05-12 122 views
1

的情況下,在這個程序:鑄造在多個虛擬繼承

class Top 
    { 
      public: 
      int a; 
    }; 

    class Left : virtual public Top 
    { 
      public: 
      int b; 
    }; 

    class Right : virtual public Top 
    { 
      public: 
      int c; 
    }; 

    class Bottom : public Left, public Right 
    { 
      public: 
      int d; 
    }; 

    class AnotherBottom : public Left, public Right 
    { 
      public: 
      int e; 
      int f; 
    }; 

    int main() 
    { 
     Bottom* bottom1 = new Bottom(); 
     AnotherBottom* bottom2 = new AnotherBottom(); 
     Top* top1 = bottom1; 
     Top* top2 = bottom2; 
     Left* left = static_cast<Left*>(top1); 
     return 0; 
    } 

我有一個關於這個計劃幾個疑惑:

做編譯器給出了錯誤

error: cannot convert from base ‘Top’ to derived type ‘Left’ via virtual base ‘Top

的的static_cast

即使在動態鑄造上也會給出錯誤

error: cannot dynamic_cast ‘top1’ (of type ‘class Top*’) to type ‘class Left*’ (source type is not polymorphic)

因此,在Top類中添加虛擬析構函數時,它變成多態,並允許動態轉換。

我無法理解爲什麼會發生這種情況。

+1

閱讀這個非常類似的問題:http://stackoverflow.com/questions/3747066/c-cannot-convert-from-base-a-to-derived-type-b-via-virtual-base-a –

回答

2

演員不能靜態完成。想象一下從Top(可能多次)和從Left幾乎繼承的類。佈局取決於該課程的細節。因此,沒有一種已知的方法可以確定Left實例的數據位於哪裏,只有Top實例位於該位置。

解決方案是將信息嵌入對象本身(作爲vtable的一部分,通常),然後動態地進行計算。因此,您可能會包含一些數據說:「我真的是Left的一個實例,而我的Top基礎實例距離我的指針指向的地方爲12個字節」。

但是C++不希望每個對象都被迫保存這些信息,因爲它通常不是必需的。它只需要被多態類存儲,而這正是那些需要有一個vtable的類(這不是巧合)。