C++在物件導向的多型部分有一種現象,叫做slice,中文叫做切割。它指的是當你試圖把衍生類別的物件轉交給基礎類別時,衍生部分被永遺地遺棄,只剩下基礎類別屬性的情形。
slice的發生絕對是令人不快的,因為它有可能會造成資源洩漏,也有可能造成不確定行為,更糟的是它的發生不會讓編譯器發生警告!
那麼什麼時候會發生slice?
slice的發生絕對是令人不快的,因為它有可能會造成資源洩漏,也有可能造成不確定行為,更糟的是它的發生不會讓編譯器發生警告!
那麼什麼時候會發生slice?
假設我們有個類別叫
在這兩個函式裡,Derived物件被upcast成Base物件[?],然而在Base類別的函式不可能知道Derived類別要如何被正確的複製,於是它不知道的部分就被遺棄了。
Base
,一個類別Derived
繼承Base
,下面是會slice的例子:void function( Base ); Base b; Derived d; b = d; // slice function( d ); // slice之所以會slice的原因是,
b = d
觸發了Base & Base::operator =( const Base & )
,而function( d )
[?]觸發了Base::Base( const Base & )
。在這兩個函式裡,Derived物件被upcast成Base物件[?],然而在Base類別的函式不可能知道Derived類別要如何被正確的複製,於是它不知道的部分就被遺棄了。
如果改成下列形式,就不會發生slice:
void function( const Base & ); Base * b; Derived d; b = &d; function( d ); // slice因為指標的指定不會喚起建構式和解構式以及指定運算子[?],而reference同樣也不會。
現在你可以知道為什麼多型物件經常以指標型式出現,以及call by const reference被推薦的原因之一了。
沒有留言:
張貼留言