日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++ 继承机制易犯的错误

發布時間:2024/4/11 c/c++ 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++ 继承机制易犯的错误 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

繼承作為面向對象的基本特征之一,其使用率極高。不管是為了實現軟件的基本功能,還是再程序的重構的過程中,我們總是會用到繼承機制。正是因為其用途極為廣泛,而且使用簡單,大眾程序員對其真正的內部實現機制的探究不是很深。而且,在大部分情況下,我們對繼承的使用方法是錯誤的。下面用例子來說明問題。

[cpp]?view plaincopy
  • class?Animal?{??
  • ???public:??
  • ???????Animal?&operator=(const?Animal?&rhs);??
  • ???????...??
  • };??
  • class?Animal1:?public?Animal?{??
  • ???public:??
  • ???????Animal1?&operator=(const?Animal1?&rhs);??
  • ???????...??
  • };??
  • class?Animal2:?public?Animal?{??
  • ???public:??
  • ???????Animal2?&operator=(const?Animal2?&rhs);??
  • ???????...??
  • };??
  • 上面的代碼只是簡單的定義一個繼承體系,即Animal作為基類,Animal1和Animal2公共繼承它。三者都重載了賦值運算符。這對于問題的說明已經足夠了。考慮下面的代碼:

    [cpp]?view plaincopy
  • Animal1?an1;??
  • Animal2?an2;??
  • Animal??*pAn1?=?&an1;??
  • Animal??*pAn2?=?&an2;??
  • ...??
  • *pAn1?=?*pAn2;??
  • 上面的代碼足夠簡單了吧!問題就出現了。我們在最后一行的目的是將an2賦值給an1.如果你不是此目的,那么可以繞開本文了!因為通過指針,對對象進行賦值動作對于c++程序員來說,非常普遍。但是實際的效果確是,an1的Animal成分與an2的Animal成分相同,而an1的Animal1成本保持不變。 這里提一下出現這種情況的原因:1.繼承體系中的賦值函數是重載,而不是覆蓋和隱藏(注意三者的區別:);2.由于Animal *pAn1 = &an1,是產生pAn1所覆蓋的范圍縮小的效果,因此當采用賦值操作時,實際上調用的賦值函數時基類的賦值函數 。這種效果是不是導致你的an1對象二不象了,既不是原來的an1對象,也不是你期待的an2對象。不過,如果你是想達到這種移花接木的效果,那么我恭喜你,這種用法太妙了,也說明你對c++ 的繼承體系已經到了一種登峰造極的地步。

    ? ? ? ? ?不過,大部分人都不是實現移花接木的功能,那么怎么實現全部成分的賦值效果呢?

    ? ? ? ? ?既然已經用到了繼承機制,那么就不得離開虛函數了。我們將賦值操作符函數定義為虛函數,代碼如下:

    [cpp]?view plaincopy
  • class?Animal?{??
  • ???public:??
  • ???????virtual?Animal?&operator=(const?Animal?&rhs);??
  • ???????...??
  • };??
  • class?Animal1:?public?Animal?{??
  • ???public:??
  • ???????virtual?Animal1?&operator=(const?Animal1?&rhs);??
  • ?...};class?Animal2:?public?Animal?{?public:?virtual?Animal2?&operator=(const?Animal2?&rhs);??
  • ...};??
  • 采用虛函數確實能夠解決上面提到的全部成分的賦值效果,因為他會導致覆蓋賦值函數,而不是上面的重載,因此會調用實際Animal1類的賦值函數。但這樣仍然會帶來問題,如下的代碼:
    [cpp]?view plaincopy
  • Animal1?an1;??
  • Animal2?an2;//這里是Animal2對象,與前面的Animal1不同??
  • Animal??*pAn1?=?&an1;??
  • Animal??*pAn2?=?&an2;??
  • ...??
  • *pAn1?=?*pAn2;//將Animal2對象賦值給Animal1??
  • 這樣子會允許異型轉換,明顯還是會出現問題。如何解決呢?可以參考《More Effective c++》里面的條款34。

    總結

    以上是生活随笔為你收集整理的c++ 继承机制易犯的错误的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。