c 中進行型別轉換時,為什麼子類可以隱式轉換到父類?

時間 2021-05-07 00:38:11

1樓:

面對物件原則之,黎克特制替換原則。

Liskov於2023年提出了乙個關於繼承的原則「Inheritance should ensure that any property proved about supertype objects also holds for subtype objects.」——「繼承必須確保超類所擁有的性質在子類中仍然成立。」也就是說,當乙個子類的例項應該能夠替換任何其超類的例項時,它們之間才具有is-A關係。

當乙個子類想要通過型別轉換成它的父類時,由於滿足黎克特制替換原則,所以該行為一定是成功的。所以這裡不需要乙個顯示的轉換行為來告訴編譯器它可以轉換。

而基礎型別,比如題主舉的「byte轉換到int」的例子這個和子類轉換到父類是不一樣的。

基礎型別的隱式轉換是以記憶體空間為條件的,比如short到int,int到long。反之就需要顯式轉換。

至於子類轉換到基類資料不丟失……你只要不把那片記憶體乾掉它都不丟。

2樓:shun

C++ 值型別語義中, 子類物件賦予基類物件,會發生物件切割(object slice),此時基類物件僅有基類大小,子類物件資料是丟失的。

在引用語義中,由於都是指標/引用,這個大小都是固定大小(指標大小),所以此時即使基類引用指向子類引用,大小都是一致的。

了解完C++的值語義和引用語義後,現在反觀C#裡的相應概念,struct定義的是值型別,class定義的是引用型別,這點對於C++稍微不同。

可以看到C#裡對於struct型別定義是不允許繼承基類,但允許實現介面。

現在回到問題裡的,子類轉換成基類的資料丟失問題,首先引用型別的資料記憶體分配都是在堆上,對於基類引用指向子類引用實際上對於子類物件的資料並沒有發生變化,而是編譯器把子類物件當做基類,並且僅允許通過基類介面訪問,而基類介面由於被子類繼承,所以子類是具備所有的的基類介面,因此這樣的操作也是合理的。

而多型的發生(虛函式override) 也可以看到對於虛函式的呼叫,IL產生的指令是callvirt,這方面感興趣的可以去深入了解虛函式呼叫機制。

BERT中進行NER為什麼沒有使用CRF,我們使用DL進行序列標註問題的時候CRF是必備麼?

不用這麼糾結哈,都試試就行了。我主要說一下我對這個問題的理解 BERT CRF的搭配中,有必要單獨給CRF轉移矩陣引數設定乙個較大的學習率嗎?之所以BERT CRF,CRF需要較大的學習率是因為BERT是預訓練模型,而CRF的轉移矩陣是隨機初始化的,這是預訓練模型和非預訓練模型的不match導致的。...

為什麼C沒有布林型別?

相對於其他高階語言,c的語法糖不多,而且c是講究強制轉換的,你用個char不就乙個位元組了嗎?由於記憶體的對齊,乙個結構體要弄成2 n這麼大才最有效率,多幾個布林變數用位元組表示,一般對記憶體沒啥影響 搞點肉蛋奶 C語言 1972年 或者說 New B 1971年 在PDP 11平台設計之初,就確定...

為什麼有人把指標轉換為int型別去傳遞?

散熱片 補充乙個freeRTOS裡的例子。排程器建立任務的函式原型 BaseType t xTaskCreate TaskFunction t pvTaskCode,任務函式指標 const char const pcName,uint16 t usStackDepth,voidpvParamete...