先講一句忠告:在使用多型的時候不能直接使用物件的強制轉換,而應該使用指標或者引用。
首先,介紹一下小知識點:
class fbase
void printinfo()
protected:
tchar *info;
};class fchild : public fbase
};
fchild child;
child.set();
child.printinfo();
((fbase)child).set();
child.printinfo();
問:兩次輸出分別是什麼?
如果你要回答兩次一次是fchild,一次是fbase,那麼你就錯了。
事實上 ((fbase)child).set() 確實呼叫的是基類的set函式,但是是由乙個臨時物件呼叫的,結果也設定到了臨時物件的身上,臨時物件此時info指標指向的是"fbase"。
但是,child物件的值仍未變,所以兩次輸出均為 fchild。
如果你明白了上面這道題,那麼下面這道題你也可以答對。
#include using std::cout;
using std::endl;
class base
void shownum()
private:
int inum;
};class derived : public base
void shownum()
private:
int idnum;
};int main()
輸出結果為:
set base inum to 100
set derived idnum to 100
inum in base: -2
idnum in derived: 100
可以看到,這裡的inum的值是不定的。原因也是給基類部分賦值的時候,把值賦給了臨時物件的緣故。
有人可能對 (fbase)child 這種強制轉換為什麼會生成臨時物件,表示不解。其實這很好解釋的。
對於c風格的強制轉換,以下兩種方式的效果是一樣的。
(t)expression //將expression轉型為t型別
t(expression) //將expression轉型為t型別
對於 (fbase)child這樣的強制轉換,可以完全等同於
fbase(child)
這樣再看的話,是不是就很清楚了。
匿名臨時物件生成了,發生了切片slicing!
再補充一句,使用static_cast(child)將產生同樣的效果,即也會生成臨時基類物件。
這也就是ec++ 條款27中的下面這個例子想要表達的。
class window
//...
};class specialwindow : public window
//...
};
解析:
static_cast(*this).onresize();//error!!!
這裡static_cast(*this) 等價於 (window)(*this),也等價於window(*this),即為建立乙個匿名基類物件,並通過切片由派生類物件構造出來。
之後,呼叫onresize()方法,確實,呼叫的是基類的方法,但是卻是臨時基類物件的!而不是派生類物件的。
如果window::onresize()修改了物件內容,那麼當前派生類物件並沒有被改動,改動的是乙個基類物件副本。這時,如果specialwindow::onresize()內如果也修改了物件,當前派生類物件真的會被修改。這使得當前的派生類物件進入了一種「傷殘」狀態:其基類部分的成分的更改沒有落實,而派生類部分的成分的更改倒落實了。
解決的方法就是拿掉強轉動作,代之以真正的靜態呼叫。
class specialwindow : public window
//...
};
最後,讓我再重複一句:在使用多型的時候不能直接使用物件的強制轉換,而應該使用指標或者引用。
C 專案面對物件的高效能物件對映總結
複製 public class article public string categoryid public string title public string pic public string host public string pichost pic.formathosturl host...
面對物件的三大特性 三 多型
動態編譯型別 同一方法可以根據傳送物件的不同而採用多種不同的行為方式。乙個物件的實際型別是確定的,但可以指向物件的引用的型別有很多。注意 多型是方法的多型,屬性沒有多型性 instanceof 乙個物件的實際型別是確定的 new student new person 但是,可以指向的引用型別就不確定...
聯想筆記本使用linux時不能連線WiFi
1.每次開機不能使用無線網,輸入 rfkill list發現ideapad laptop處於blocked yes狀態,使用以下命令解除鎖定便可以使用wifi。sudo modprobe r ideapad laptop2.將ideapad laptop列入黑名單,以後開機不用每次手動移除 sudo...