TAG

首都機能移轉 (2) 歌詞 (2) 靠北文 (40) 戲言 (30) 糟糕 (7) ACG (23) Assembly (2) Boost (2) C (31) C++ (69) CMake (4) CSIE (67) Debian (34) Design_Pattern (2) Django (1) Eclipse (1) en_US (13) FFmpeg (3) FoolproofProject (26) FreeBSD (2) Git (4) GNU_Linux (65) IDE (5) Java (11) JavaScript (19) KDE (15) Khopper (16) KomiX (3) Kubuntu (18) Life (1) Lighttpd (2) Mac_OS_X (2) Opera (1) PHP (2) PicKing (2) Programing (21) Prolog (1) Python (7) QSnapshot (2) Qt (30) Qt_Jambi (1) Regular_Expression (1) Shell_Script (7) Talk (98) VirtualBox (7) Visual_Studio (13) Windows (18) zh_TW (36)

2008年7月19日 星期六

When the slices happen?

C++在物件導向的多型部分有一種現象,叫做slice,中文叫做切割。它指的是當你試圖把衍生類別的物件轉交給基礎類別時,衍生部分被永遺地遺棄,只剩下基礎類別屬性的情形。
slice的發生絕對是令人不快的,因為它有可能會造成資源洩漏,也有可能造成不確定行為,更糟的是它的發生不會讓編譯器發生警告!
那麼什麼時候會發生slice?
假設我們有個類別叫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被推薦的原因之一了。

沒有留言:

張貼留言