2014-09-03 76 views
3

在最近的一位開發者遇到了Swift中繼承的struct這個話題(或者更確切地說,Swift中缺少繼承的struct)。我認爲爲什麼斯威夫特不支持struct繼承的原因是因爲:C++和Swift:如何在C++堆棧框架中處理結構?結構繼承的複雜性是爲什麼Swift不支持結構繼承?

  • struct s爲值類型
  • 值類型是堆棧幀之間複製
  • 繼承將意味着一個struct的大小可以變化(例如,如果從VehicleLorry繼承和Lorry添加然後Lorry需要比Vehicle更多空間)
  • 具有值類型參數s的未在編譯時已知會呼叫者和複雜堆棧幀結構大小訪問數據爲被叫

我認爲,這是因爲這些併發症,這大概會增加額外的操作,每一個的函數調用涉及struct並因此降低性能,Swift不允許struct繼承。這個推理是否正確?

但是,然後我儘管關於C++。 C++確實允許struct繼承,並且C++非常注重性能。這讓我覺得我的推理不允許struct繼承是錯誤的。 C++如何實現struct繼承而不會對性能產生負面影響?

回答

4

C++如何在不影響性能的情況下實現結構體繼承?

在C++中,編譯器總是知道一個struct的大小。但是當一個基類被值複製時,對象就會被「切片」:只有基類的成員被複制,並且新對象與原始對象的派生類沒有任何關係。

因此,如果函數想要在不切斷其額外標識的情況下使用Vehicle執行某些操作,則必須使用指針或參考Vehicle作爲函數參數類型或返回類型。但是到那時您不再有「在棧幀之間複製的值類型」。

0

由於結構是值類型,所以應該將它們複製到函數中並返回。所以,你可以調用與派生結構爲非不同誘變的方法,但將無法返回從中派生值,所以

struct Vehicle { 
    var color: Color 

    mutating func paintWhite() { 
     self.color = .White 
    } 
} 


struct Lorry: Vehicle ... 

var lorry = Lorry(color:.Blue) 
lorry.paintWhite() // <- wouldn't work, as paintWhite takes inout Vehicle 

不叫突變方法結構的能力將是有益的少得多,並更令人困惑。