使用多型的時,不能對 物件本身進行強制轉換

2021-07-02 18:44:39 字數 2178 閱讀 1653

先講一句忠告:在使用多型的時候不能直接使用物件的強制轉換,而應該使用指標或者引用

首先,介紹一下小知識點:

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...