| 订阅 | 在线投稿
分享
 
 
 

C++中的虚函数(virtual function)(1)

2008-06-01 02:06:36 编辑來源:互联网 国际版 评论
 
 
本文为【C++中的虚函数(virtual function)(1)】的汉字拼音对照版显示拼音
  yi.jianjie

  xuhanshushiC++zhongyongyushixianduotai(polymorphism)dejizhigaixinlinianjiushitongguojilei访fangwenpaishengleidingyidehanshujiashewomenyouxiamiandeleicengci

  class A

  {

  public:

  virtual void foo() { cout << "A::foo() is called" << endl;}

  };

  class B: public A

  {

  public:

  virtual void foo() { cout << "B::foo() is called" << endl;}

  };

  namezai使shiyongdeshihouwomenkeyi

  A * a = new B();

  a->foo(); // zaizheliasuiranshizhixiangAdezhizhendanshibeitiaoyongdehanshu(foo)queshiBde!

  zhegelizishixuhanshudeyigedianxingyingyongtongguozhegeliziyexunijiuduixuhanshuyouleyixiegainiantaxujiuxuzaisuoweituichilianbianhuozhedongtailianbianshangyigeleihanshudetiaoyongbingbushizaibianyishikebeiquedingdeershizaiyunxingshikebeiquedingdeyouyubianxiedaimadeshihoubingbunengquedingbeitiaoyongdeshijileidehanshuhuanshinagepaishengleidehanshusuoyibeichengweixuhanshu

  xuhanshuzhinengjiezhuyuzhizhenhuozheyinyonglaidadaoduotaidexiaoguojiarushixiamianzheyangdedaimazesuiranshixuhanshudantabushiduotaide

  class A

  {

  public:

  virtual void foo();

  };

  class B: public A

  {

  virtual void foo();

  };

  void bar()

  {

  A a;

  a.foo(); // A::foo()beitiaoyong

  }

  1.1 duotai

  zailejielexuhanshudeyisizhihouzaikaolvshenmeshiduotaijiuhenqingyilerengranzhenduishangmiandeleicengcidanshi使shiyongdefangfabiandefuduoleyixie

  void bar(A * a)

  {

  a->foo(); // beitiaoyongdeshiA::foo() huanshiB::foo()

  }

  yinweifoo()shigexuhanshusuoyizaibarzhegehanshuzhongzhigenjuzheduandaimawucongquedingzhelibeitiaoyongdeshiA::foo()huanshiB::foo()danshikeyikendingdeshuojiaruazhixiangdeshiAleideshilizeA::foo()beitiaoyongjiaruazhixiangdeshiBleideshilizeB::foo()beitiaoyong

  zhezhongtongyidaimakeyichanshengbutongxiaoguodetedianbeichengweiduotai

  1.2 duotaiyoushenmeyong

  duotaizhemeshenqidanshinengyonglaizuoshenmenezhegemingtiwonanyiyongyiliangjuhuagaikuoyibandeC++jiaochenghuozheqitamianxiangduixiangyuyandejiaochengdouyongyigehuatudelizilaizhanshiduotaideyongtuwojiubuzaichongfuzhegelizilejiarunibuzhidaozhegelizisui便bianzhaobenshuyinggaidouyoujieshaowoshitucongyigechouxiangdejiaodumiaoshuyixiahuitouzaijiehenagehuatudeliziyexunijiugengqingyilijie

  zaimianxiangduixiangdebianchengzhongshouxianhuizhenduishujujinxingchouxiangquedingjileihejixuquedingpaishengleigouchengleicengcizhegeleicengcide使shiyongzhezai使shiyongtamendeshihoujiarurengranzaixuyaojileideshihouxiezhenduijileidedaimazaixuyaopaishengleideshihouxiezhenduipaishengleidedaimajiudengyuleicengciwanquanbaoluzai使shiyongzhemianqianjiaruzhegeleicengciyourenhedegaibianzengjialexinleidouxuyao使shiyongzhezhidaozhenduixinleixiedaimazheyangjiuzengjialeleicengciyuqi使shiyongzhezhijiandeouheyourenbazhezhongqingkuanglieweichengxuzhongdebad smellzhiyi

  duotaikeyi使shichengxuyuantuolizhezhongjiongjingzaihuitoukankan1.1zhongdelizibar()zuoweiA-Bzhegeleicengcide使shiyongzhetabingbuzhidaozhegeleicengcizhongyouduoshaogeleimeigeleidoujiaoshenmedanshiyiyangkeyihenhaodegongzuodangyouyigeCleicongAleipaishengchulaihoubar()yebuxuyaozhidaoxiugaizhewanquanguigongyuduotai--bianyiqizhenduixuhanshuchanshenglekeyizaiyunxingshikequedingbeitiaoyonghanshudedaima

  1.3 ruhedongtailianbian

  bianyiqishiruhezhenduixuhanshuchanshengkeyizaiyunxingshikequedingbeitiaoyonghanshudedaimaneyejiushishuoxuhanshushijishangshiruhebeibianyiqichulideneLippmanzaishendutansuoC++duixiangmoxing[1]zhongdebutongzhangjiejiangdaolejizhongfangshizhelibabiaozhundefangshijiandanjieshaoyixia

  wosuoshuodebiaozhunfangshiyejiushisuoweideVTABLEjizhibianyiqifaxianyigeleizhongyoubeishengmingweivirtualdehanshujiuhuiweiqigaoyigexuhanshubiaoyejiushiVTABLEVTABLEshijishangshiyigehanshuzhizhendeshuzumeigexuhanshuzhanyongzhegeshuzudeyigeslotyigeleizhiyouyigeVTABLEbuguantayouduoshaogeshilipaishengleiyouzijideVTABLEdanshipaishengleideVTABLEyujileideVTABLEyouxiangtongdehanshupailieshunxutongmingdexuhanshubeifangzailianggeshuzudexiangtongweizhishangzaichuangjianleishilideshihoubianyiqihuanhuizaimeigeshilideneicunbujuzhongzengjiayigevptrziduangaiziduanzhixiangbenleideVTABLEtongguozhexieshouduanbianyiqizaikandaoyigexuhanshutiaoyongdeshihoujiuhuijiangzhegetiaoyonggaixiezhendui1.1zhongdelizi

  void bar(A * a)

  {

  a->foo();

  }

  huibeigaixiewei

  void bar(A * a)

  {

  (a->vptr[1])();

  }

  yinweipaishengleihejileidefoo()hanshujuyouxiangtongdeVTABLEsuoyinertamendevptryouzhixiangbutongdeVTABLEyincitongguozheyangdefangfakeyizaiyunxingshikejuedingtiaoyongnagefoo()hanshu

  suiranshijiqingkuangyuanfeizhemejiandandanshijibenyuanlidazhiruci

  1.4 overloadheoverride

  xuhanshuzongshizaipaishengleizhongbeigaixiezhezhonggaixiebeichengweioverridewojingchanghunxiaooverloadheoverridezhelianggedancidanshisuizhegeleiC++deshuyuelaiyueduohoulaidechengxuyuanyexubuhuizaifanwofanguodecuowuledanshiwodasuanchengqingyixia

  overrideshizhipaishengleichongxiejileidexuhanshujiuxiangwomenqianmianBleizhongchongxieleAleizhongdefoo()hanshuchongxiedehanshubixuyouyizhideshenshubiaohefanhuizhiC++biaozhundayingfanhuizhibutongdeqingkuangzhegewohuizaiyufabufenjiandanjieshaodanshihenshaobianyiqizhichizhegefeaturezhegedancihaoxiangyizhimeiyoushenmeheshidezhongwencihuilaiduiyingyourenyiweifugaihuantieqieyixie

  overloadyuedingchengsudebeifanyiweichongzaishizhibianxieyigeyuyiyouhanshutongmingdanshishenshubiaobutongdehanshuliruyigehanshujikeyijieshouzhengxingshuzuoweishenshuyekeyijieshoufudianshuzuoweishenshu

  yi.jianjie

  

  

  xuhanshushiC++zhongyongyushixianduotai(polymorphism)dejizhigaixinlinianjiushitongguojilei访fangwenpaishengleidingyidehanshujiashewomenyouxiamiandeleicengci

  class A

  {

  public:

  virtual void foo() { cout << "A::foo() is called" << endl;}

  };

  class B: public A

  {

  public:

  virtual void foo() { cout << "B::foo() is called" << endl;}

  };

  namezai使shiyongdeshihouwomenkeyi

  A * a = new B();

  a->foo(); // zaizheliasuiranshizhixiangAdezhizhendanshibeitiaoyongdehanshu(foo)queshiBde!

  zhegelizishixuhanshudeyigedianxingyingyongtongguozhegeliziyexunijiuduixuhanshuyouleyixiegainiantaxujiuxuzaisuoweituichilianbianhuozhedongtailianbianshangyigeleihanshudetiaoyongbingbushizaibianyishikebeiquedingdeershizaiyunxingshikebeiquedingdeyouyubianxiedaimadeshihoubingbunengquedingbeitiaoyongdeshijileidehanshuhuanshinagepaishengleidehanshusuoyibeichengweixuhanshu

  xuhanshuzhinengjiezhuyuzhizhenhuozheyinyonglaidadaoduotaidexiaoguojiarushixiamianzheyangdedaimazesuiranshixuhanshudantabushiduotaide

  class A

  {

  public:

  virtual void foo();

  };

  class B: public A

  {

  virtual void foo();

  };

  void bar()

  {

  A a;

  a.foo(); // A::foo()beitiaoyong

  }

  1.1 duotai

  zailejielexuhanshudeyisizhihouzaikaolvshenmeshiduotaijiuhenqingyilerengranzhenduishangmiandeleicengcidanshi使shiyongdefangfabiandefuduoleyixie

  void bar(A * a)

  {

  a->foo(); // beitiaoyongdeshiA::foo() huanshiB::foo()

  }

  yinweifoo()shigexuhanshusuoyizaibarzhegehanshuzhongzhigenjuzheduandaimawucongquedingzhelibeitiaoyongdeshiA::foo()huanshiB::foo()danshikeyikendingdeshuojiaruazhixiangdeshiAleideshilizeA::foo()beitiaoyongjiaruazhixiangdeshiBleideshilizeB::foo()beitiaoyong

  zhezhongtongyidaimakeyichanshengbutongxiaoguodetedianbeichengweiduotai

  1.2 duotaiyoushenmeyong

  duotaizhemeshenqidanshinengyonglaizuoshenmenezhegemingtiwonanyiyongyiliangjuhuagaikuoyibandeC++jiaochenghuozheqitamianxiangduixiangyuyandejiaochengdouyongyigehuatudelizilaizhanshiduotaideyongtuwojiubuzaichongfuzhegelizilejiarunibuzhidaozhegelizisui便bianzhaobenshuyinggaidouyoujieshaowoshitucongyigechouxiangdejiaodumiaoshuyixiahuitouzaijiehenagehuatudeliziyexunijiugengqingyilijie

  zaimianxiangduixiangdebianchengzhongshouxianhuizhenduishujujinxingchouxiangquedingjileihejixuquedingpaishengleigouchengleicengcizhegeleicengcide使shiyongzhezai使shiyongtamendeshihoujiarurengranzaixuyaojileideshihouxiezhenduijileidedaimazaixuyaopaishengleideshihouxiezhenduipaishengleidedaimajiudengyuleicengciwanquanbaoluzai使shiyongzhemianqianjiaruzhegeleicengciyourenhedegaibianzengjialexinleidouxuyao使shiyongzhezhidaozhenduixinleixiedaimazheyangjiuzengjialeleicengciyuqi使shiyongzhezhijiandeouheyourenbazhezhongqingkuanglieweichengxuzhongdebad smellzhiyi

  duotaikeyi使shichengxuyuantuolizhezhongjiongjingzaihuitoukankan1.1zhongdelizibar()zuoweiA-Bzhegeleicengcide使shiyongzhetabingbuzhidaozhegeleicengcizhongyouduoshaogeleimeigeleidoujiaoshenmedanshiyiyangkeyihenhaodegongzuodangyouyigeCleicongAleipaishengchulaihoubar()yebuxuyaozhidaoxiugaizhewanquanguigongyuduotai--bianyiqizhenduixuhanshuchanshenglekeyizaiyunxingshikequedingbeitiaoyonghanshudedaima

  1.3 ruhedongtailianbian

  bianyiqishiruhezhenduixuhanshuchanshengkeyizaiyunxingshikequedingbeitiaoyonghanshudedaimaneyejiushishuoxuhanshushijishangshiruhebeibianyiqichulideneLippmanzaishendutansuoC++duixiangmoxing[1]zhongdebutongzhangjiejiangdaolejizhongfangshizhelibabiaozhundefangshijiandanjieshaoyixia

  wosuoshuodebiaozhunfangshiyejiushisuoweideVTABLEjizhibianyiqifaxianyigeleizhongyoubeishengmingweivirtualdehanshujiuhuiweiqigaoyigexuhanshubiaoyejiushiVTABLEVTABLEshijishangshiyigehanshuzhizhendeshuzumeigexuhanshuzhanyongzhegeshuzudeyigeslotyigeleizhiyouyigeVTABLEbuguantayouduoshaogeshilipaishengleiyouzijideVTABLEdanshipaishengleideVTABLEyujileideVTABLEyouxiangtongdehanshupailieshunxutongmingdexuhanshubeifangzailianggeshuzudexiangtongweizhishangzaichuangjianleishilideshihoubianyiqihuanhuizaimeigeshilideneicunbujuzhongzengjiayigevptrziduangaiziduanzhixiangbenleideVTABLEtongguozhexieshouduanbianyiqizaikandaoyigexuhanshutiaoyongdeshihoujiuhuijiangzhegetiaoyonggaixiezhendui1.1zhongdelizi

  void bar(A * a)

  {

  a->foo();

  }

  huibeigaixiewei

  void bar(A * a)

  {

  (a->vptr[1])();

  }

  yinweipaishengleihejileidefoo()hanshujuyouxiangtongdeVTABLEsuoyinertamendevptryouzhixiangbutongdeVTABLEyincitongguozheyangdefangfakeyizaiyunxingshikejuedingtiaoyongnagefoo()hanshu

  suiranshijiqingkuangyuanfeizhemejiandandanshijibenyuanlidazhiruci

  1.4 overloadheoverride

  xuhanshuzongshizaipaishengleizhongbeigaixiezhezhonggaixiebeichengweioverridewojingchanghunxiaooverloadheoverridezhelianggedancidanshisuizhegeleiC++deshuyuelaiyueduohoulaidechengxuyuanyexubuhuizaifanwofanguodecuowuledanshiwodasuanchengqingyixia

  overrideshizhipaishengleichongxiejileidexuhanshujiuxiangwomenqianmianBleizhongchongxieleAleizhongdefoo()hanshuchongxiedehanshubixuyouyizhideshenshubiaohefanhuizhiC++biaozhundayingfanhuizhibutongdeqingkuangzhegewohuizaiyufabufenjiandanjieshaodanshihenshaobianyiqizhichizhegefeaturezhegedancihaoxiangyizhimeiyoushenmeheshidezhongwencihuilaiduiyingyourenyiweifugaihuantieqieyixie

  overloadyuedingchengsudebeifanyiweichongzaishizhibianxieyigeyuyiyouhanshutongmingdanshishenshubiaobutongdehanshuliruyigehanshujikeyijieshouzhengxingshuzuoweishenshuyekeyijieshoufudianshuzuoweishenshu QQread.com tuichuyouxigonglue http://www.qqread.com/netgame/game/index.Html moshoushijie paopaokadingche jietoulanqiu shuihuQchuan longyudixiachengOL zhengfu xuanyuanjian5 FIFA07 rexuejianghu datangfengyun menghuan西xiyou wulinwaichuan

  yi.jianjie

  

  

  xuhanshushiC++zhongyongyushixianduotai(polymorphism)dejizhigaixinlinianjiushitongguojilei访fangwenpaishengleidingyidehanshujiashewomenyouxiamiandeleicengci

  class A

  {

  public:

  virtual void foo() { cout << "A::foo() is called" << endl;}

  };

  class B: public A

  {

  public:

  virtual void foo() { cout << "B::foo() is called" << endl;}

  };

  namezai使shiyongdeshihouwomenkeyi

  A * a = new B();

  a->foo(); // zaizheliasuiranshizhixiangAdezhizhendanshibeitiaoyongdehanshu(foo)queshiBde!

  zhegelizishixuhanshudeyigedianxingyingyongtongguozhegeliziyexunijiuduixuhanshuyouleyixiegainiantaxujiuxuzaisuoweituichilianbianhuozhedongtailianbianshangyigeleihanshudetiaoyongbingbushizaibianyishikebeiquedingdeershizaiyunxingshikebeiquedingdeyouyubianxiedaimadeshihoubingbunengquedingbeitiaoyongdeshijileidehanshuhuanshinagepaishengleidehanshusuoyibeichengweixuhanshu

  xuhanshuzhinengjiezhuyuzhizhenhuozheyinyonglaidadaoduotaidexiaoguojiarushixiamianzheyangdedaimazesuiranshixuhanshudantabushiduotaide

  class A

  {

  public:

  virtual void foo();

  };

  class B: public A

  {

  virtual void foo();

  };

  void bar()

  {

  A a;

  a.foo(); // A::foo()beitiaoyong

  }

  1.1 duotai

  zailejielexuhanshudeyisizhihouzaikaolvshenmeshiduotaijiuhenqingyilerengranzhenduishangmiandeleicengcidanshi使shiyongdefangfabiandefuduoleyixie

  void bar(A * a)

  {

  a->foo(); // beitiaoyongdeshiA::foo() huanshiB::foo()

  }

  yinweifoo()shigexuhanshusuoyizaibarzhegehanshuzhongzhigenjuzheduandaimawucongquedingzhelibeitiaoyongdeshiA::foo()huanshiB::foo()danshikeyikendingdeshuojiaruazhixiangdeshiAleideshilizeA::foo()beitiaoyongjiaruazhixiangdeshiBleideshilizeB::foo()beitiaoyong

  zhezhongtongyidaimakeyichanshengbutongxiaoguodetedianbeichengweiduotai

  1.2 duotaiyoushenmeyong

  duotaizhemeshenqidanshinengyonglaizuoshenmenezhegemingtiwonanyiyongyiliangjuhuagaikuoyibandeC++jiaochenghuozheqitamianxiangduixiangyuyandejiaochengdouyongyigehuatudelizilaizhanshiduotaideyongtuwojiubuzaichongfuzhegelizilejiarunibuzhidaozhegelizisui便bianzhaobenshuyinggaidouyoujieshaowoshitucongyigechouxiangdejiaodumiaoshuyixiahuitouzaijiehenagehuatudeliziyexunijiugengqingyilijie

  zaimianxiangduixiangdebianchengzhongshouxianhuizhenduishujujinxingchouxiangquedingjileihejixuquedingpaishengleigouchengleicengcizhegeleicengcide使shiyongzhezai使shiyongtamendeshihoujiarurengranzaixuyaojileideshihouxiezhenduijileidedaimazaixuyaopaishengleideshihouxiezhenduipaishengleidedaimajiudengyuleicengciwanquanbaoluzai使shiyongzhemianqianjiaruzhegeleicengciyourenhedegaibianzengjialexinleidouxuyao使shiyongzhezhidaozhenduixinleixiedaimazheyangjiuzengjialeleicengciyuqi使shiyongzhezhijiandeouheyourenbazhezhongqingkuanglieweichengxuzhongdebad smellzhiyi

  duotaikeyi使shichengxuyuantuolizhezhongjiongjingzaihuitoukankan1.1zhongdelizibar()zuoweiA-Bzhegeleicengcide使shiyongzhetabingbuzhidaozhegeleicengcizhongyouduoshaogeleimeigeleidoujiaoshenmedanshiyiyangkeyihenhaodegongzuodangyouyigeCleicongAleipaishengchulaihoubar()yebuxuyaozhidaoxiugaizhewanquanguigongyuduotai--bianyiqizhenduixuhanshuchanshenglekeyizaiyunxingshikequedingbeitiaoyonghanshudedaima

  1.3 ruhedongtailianbian

  bianyiqishiruhezhenduixuhanshuchanshengkeyizaiyunxingshikequedingbeitiaoyonghanshudedaimaneyejiushishuoxuhanshushijishangshiruhebeibianyiqichulideneLippmanzaishendutansuoC++duixiangmoxing[1]zhongdebutongzhangjiejiangdaolejizhongfangshizhelibabiaozhundefangshijiandanjieshaoyixia

  wosuoshuodebiaozhunfangshiyejiushisuoweideVTABLEjizhibianyiqifaxianyigeleizhongyoubeishengmingweivirtualdehanshujiuhuiweiqigaoyigexuhanshubiaoyejiushiVTABLEVTABLEshijishangshiyigehanshuzhizhendeshuzumeigexuhanshuzhanyongzhegeshuzudeyigeslotyigeleizhiyouyigeVTABLEbuguantayouduoshaogeshilipaishengleiyouzijideVTABLEdanshipaishengleideVTABLEyujileideVTABLEyouxiangtongdehanshupailieshunxutongmingdexuhanshubeifangzailianggeshuzudexiangtongweizhishangzaichuangjianleishilideshihoubianyiqihuanhuizaimeigeshilideneicunbujuzhongzengjiayigevptrziduangaiziduanzhixiangbenleideVTABLEtongguozhexieshouduanbianyiqizaikandaoyigexuhanshutiaoyongdeshihoujiuhuijiangzhegetiaoyonggaixiezhendui1.1zhongdelizi

  void bar(A * a)

  {

  a->foo();

  }

  huibeigaixiewei

  void bar(A * a)

  {

  (a->vptr[1])();

  }

  yinweipaishengleihejileidefoo()hanshujuyouxiangtongdeVTABLEsuoyinertamendevptryouzhixiangbutongdeVTABLEyincitongguozheyangdefangfakeyizaiyunxingshikejuedingtiaoyongnagefoo()hanshu

  suiranshijiqingkuangyuanfeizhemejiandandanshijibenyuanlidazhiruci

  1.4 overloadheoverride

  xuhanshuzongshizaipaishengleizhongbeigaixiezhezhonggaixiebeichengweioverridewojingchanghunxiaooverloadheoverridezhelianggedancidanshisuizhegeleiC++deshuyuelaiyueduohoulaidechengxuyuanyexubuhuizaifanwofanguodecuowuledanshiwodasuanchengqingyixia

  overrideshizhipaishengleichongxiejileidexuhanshujiuxiangwomenqianmianBleizhongchongxieleAleizhongdefoo()hanshuchongxiedehanshubixuyouyizhideshenshubiaohefanhuizhiC++biaozhundayingfanhuizhibutongdeqingkuangzhegewohuizaiyufabufenjiandanjieshaodanshihenshaobianyiqizhichizhegefeaturezhegedancihaoxiangyizhimeiyoushenmeheshidezhongwencihuilaiduiyingyourenyiweifugaihuantieqieyixie

  overloadyuedingchengsudebeifanyiweichongzaishizhibianxieyigeyuyiyouhanshutongmingdanshishenshubiaobutongdehanshuliruyigehanshujikeyijieshouzhengxingshuzuoweishenshuyekeyijieshoufudianshuzuoweishenshu QQread.com tuichuyouxigonglue http://www.qqread.com/netgame/game/index.html moshoushijie paopaokadingche jietoulanqiu shuihuQchuan longyudixiachengOL zhengfu xuanyuanjian5 FIFA07 rexuejianghu datangfengyun menghuan西xiyou wulinwaichuan

  yi.jianjie

  

  

  xuhanshushiC++zhongyongyushixianduotai(polymorphism)dejizhigaixinlinianjiushitongguojilei访fangwenpaishengleidingyidehanshujiashewomenyouxiamiandeleicengci

  class A

  {

  public:

  virtual void foo() { cout << "A::foo() is called" << endl;}

  };

  class B: public A

  {

  public:

  virtual void foo() { cout << "B::foo() is called" << endl;}

  };

  namezai使shiyongdeshihouwomenkeyi

  A * a = new B();

  a->foo(); // zaizheliasuiranshizhixiangAdezhizhendanshibeitiaoyongdehanshu(foo)queshiBde!

  zhegelizishixuhanshudeyigedianxingyingyongtongguozhegeliziyexunijiuduixuhanshuyouleyixiegainiantaxujiuxuzaisuoweituichilianbianhuozhedongtailianbianshangyigeleihanshudetiaoyongbingbushizaibianyishikebeiquedingdeershizaiyunxingshikebeiquedingdeyouyubianxiedaimadeshihoubingbunengquedingbeitiaoyongdeshijileidehanshuhuanshinagepaishengleidehanshusuoyibeichengweixuhanshu

  xuhanshuzhinengjiezhuyuzhizhenhuozheyinyonglaidadaoduotaidexiaoguojiarushixiamianzheyangdedaimazesuiranshixuhanshudantabushiduotaide

  class A

  {

  public:

  virtual void foo();

  };

  class B: public A

  {

  virtual void foo();

  };

  void bar()

  {

  A a;

  a.foo(); // A::foo()beitiaoyong

  }

  1.1 duotai

  zailejielexuhanshudeyisizhihouzaikaolvshenmeshiduotaijiuhenqingyilerengranzhenduishangmiandeleicengcidanshi使shiyongdefangfabiandefuduoleyixie

  void bar(A * a)

  {

  a->foo(); // beitiaoyongdeshiA::foo() huanshiB::foo()

  }

  yinweifoo()shigexuhanshusuoyizaibarzhegehanshuzhongzhigenjuzheduandaimawucongquedingzhelibeitiaoyongdeshiA::foo()huanshiB::foo()danshikeyikendingdeshuojiaruazhixiangdeshiAleideshilizeA::foo()beitiaoyongjiaruazhixiangdeshiBleideshilizeB::foo()beitiaoyong

  zhezhongtongyidaimakeyichanshengbutongxiaoguodetedianbeichengweiduotai

  1.2 duotaiyoushenmeyong

  duotaizhemeshenqidanshinengyonglaizuoshenmenezhegemingtiwonanyiyongyiliangjuhuagaikuoyibandeC++jiaochenghuozheqitamianxiangduixiangyuyandejiaochengdouyongyigehuatudelizilaizhanshiduotaideyongtuwojiubuzaichongfuzhegelizilejiarunibuzhidaozhegelizisui便bianzhaobenshuyinggaidouyoujieshaowoshitucongyigechouxiangdejiaodumiaoshuyixiahuitouzaijiehenagehuatudeliziyexunijiugengqingyilijie

  zaimianxiangduixiangdebianchengzhongshouxianhuizhenduishujujinxingchouxiangquedingjileihejixuquedingpaishengleigouchengleicengcizhegeleicengcide使shiyongzhezai使shiyongtamendeshihoujiarurengranzaixuyaojileideshihouxiezhenduijileidedaimazaixuyaopaishengleideshihouxiezhenduipaishengleidedaimajiudengyuleicengciwanquanbaoluzai使shiyongzhemianqianjiaruzhegeleicengciyourenhedegaibianzengjialexinleidouxuyao使shiyongzhezhidaozhenduixinleixiedaimazheyangjiuzengjialeleicengciyuqi使shiyongzhezhijiandeouheyourenbazhezhongqingkuanglieweichengxuzhongdebad smellzhiyi

  duotaikeyi使shichengxuyuantuolizhezhongjiongjingzaihuitoukankan1.1zhongdelizibar()zuoweiA-Bzhegeleicengcide使shiyongzhetabingbuzhidaozhegeleicengcizhongyouduoshaogeleimeigeleidoujiaoshenmedanshiyiyangkeyihenhaodegongzuodangyouyigeCleicongAleipaishengchulaihoubar()yebuxuyaozhidaoxiugaizhewanquanguigongyuduotai--bianyiqizhenduixuhanshuchanshenglekeyizaiyunxingshikequedingbeitiaoyonghanshudedaima

  1.3 ruhedongtailianbian

  bianyiqishiruhezhenduixuhanshuchanshengkeyizaiyunxingshikequedingbeitiaoyonghanshudedaimaneyejiushishuoxuhanshushijishangshiruhebeibianyiqichulideneLippmanzaishendutansuoC++duixiangmoxing[1]zhongdebutongzhangjiejiangdaolejizhongfangshizhelibabiaozhundefangshijiandanjieshaoyixia

  wosuoshuodebiaozhunfangshiyejiushisuoweideVTABLEjizhibianyiqifaxianyigeleizhongyoubeishengmingweivirtualdehanshujiuhuiweiqigaoyigexuhanshubiaoyejiushiVTABLEVTABLEshijishangshiyigehanshuzhizhendeshuzumeigexuhanshuzhanyongzhegeshuzudeyigeslotyigeleizhiyouyigeVTABLEbuguantayouduoshaogeshilipaishengleiyouzijideVTABLEdanshipaishengleideVTABLEyujileideVTABLEyouxiangtongdehanshupailieshunxutongmingdexuhanshubeifangzailianggeshuzudexiangtongweizhishangzaichuangjianleishilideshihoubianyiqihuanhuizaimeigeshilideneicunbujuzhongzengjiayigevptrziduangaiziduanzhixiangbenleideVTABLEtongguozhexieshouduanbianyiqizaikandaoyigexuhanshutiaoyongdeshihoujiuhuijiangzhegetiaoyonggaixiezhendui1.1zhongdelizi

  void bar(A * a)

  {

  a->foo();

  }

  huibeigaixiewei

  void bar(A * a)

  {

  (a->vptr[1])();

  }

  yinweipaishengleihejileidefoo()hanshujuyouxiangtongdeVTABLEsuoyinertamendevptryouzhixiangbutongdeVTABLEyincitongguozheyangdefangfakeyizaiyunxingshikejuedingtiaoyongnagefoo()hanshu

  suiranshijiqingkuangyuanfeizhemejiandandanshijibenyuanlidazhiruci

  1.4 overloadheoverride

  xuhanshuzongshizaipaishengleizhongbeigaixiezhezhonggaixiebeichengweioverridewojingchanghunxiaooverloadheoverridezhelianggedancidanshisuizhegeleiC++deshuyuelaiyueduohoulaidechengxuyuanyexubuhuizaifanwofanguodecuowuledanshiwodasuanchengqingyixia

  overrideshizhipaishengleichongxiejileidexuhanshujiuxiangwomenqianmianBleizhongchongxieleAleizhongdefoo()hanshuchongxiedehanshubixuyouyizhideshenshubiaohefanhuizhiC++biaozhundayingfanhuizhibutongdeqingkuangzhegewohuizaiyufabufenjiandanjieshaodanshihenshaobianyiqizhichizhegefeaturezhegedancihaoxiangyizhimeiyoushenmeheshidezhongwencihuilaiduiyingyourenyiweifugaihuantieqieyixie

  overloadyuedingchengsudebeifanyiweichongzaishizhibianxieyigeyuyiyouhanshutongmingdanshishenshubiaobutongdehanshuliruyigehanshujikeyijieshouzhengxingshuzuoweishenshuyekeyijieshoufudianshuzuoweishenshu QQread.com tuichuyouxigonglue http://www.qqread.com/netgame/game/index.html moshoushijie paopaokadingche jietoulanqiu shuihuQchuan longyudixiachengOL zhengfu xuanyuanjian5 FIFA07 rexuejianghu datangfengyun menghuan西xiyou wulinwaichuan

  

   right"chuchuqingfengruanjianxiazaixueyuan原文
 
 
一.简介 虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。假设我们有下面的类层次: class A { public: virtual void foo() { cout << "A::foo() is called" << endl;} }; class B: public A { public: virtual void foo() { cout << "B::foo() is called" << endl;} }; 那么,在使用的时候,我们可以: A * a = new B(); a->foo(); // 在这里,a虽然是指向A的指针,但是被调用的函数(foo)却是B的! 这个例子是虚函数的一个典型应用,通过这个例子,也许你就对虚函数有了一些概念。它虚就虚在所谓“推迟联编”或者“动态联编”上,一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的。由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被成为“虚”函数。 虚函数只能借助于指针或者引用来达到多态的效果,假如是下面这样的代码,则虽然是虚函数,但它不是多态的: class A { public: virtual void foo(); }; class B: public A { virtual void foo(); }; void bar() { A a; a.foo(); // A::foo()被调用 } 1.1 多态 在了解了虚函数的意思之后,再考虑什么是多态就很轻易了。仍然针对上面的类层次,但是使用的方法变的复杂了一些: void bar(A * a) { a->foo(); // 被调用的是A::foo() 还是B::foo()? } 因为foo()是个虚函数,所以在bar这个函数中,只根据这段代码,无从确定这里被调用的是A::foo()还是B::foo(),但是可以肯定的说:假如a指向的是A类的实例,则A::foo()被调用,假如a指向的是B类的实例,则B::foo()被调用。 这种同一代码可以产生不同效果的特点,被称为“多态”。 1.2 多态有什么用? 多态这么神奇,但是能用来做什么呢?这个命题我难以用一两句话概括,一般的C++教程(或者其它面向对象语言的教程)都用一个画图的例子来展示多态的用途,我就不再重复这个例子了,假如你不知道这个例子,随便找本书应该都有介绍。我试图从一个抽象的角度描述一下,回头再结合那个画图的例子,也许你就更轻易理解。 在面向对象的编程中,首先会针对数据进行抽象(确定基类)和继续(确定派生类),构成类层次。这个类层次的使用者在使用它们的时候,假如仍然在需要基类的时候写针对基类的代码,在需要派生类的时候写针对派生类的代码,就等于类层次完全暴露在使用者面前。假如这个类层次有任何的改变(增加了新类),都需要使用者“知道”(针对新类写代码)。这样就增加了类层次与其使用者之间的耦合,有人把这种情况列为程序中的“bad smell”之一。 多态可以使程序员脱离这种窘境。再回头看看1.1中的例子,bar()作为A-B这个类层次的使用者,它并不知道这个类层次中有多少个类,每个类都叫什么,但是一样可以很好的工作,当有一个C类从A类派生出来后,bar()也不需要“知道”(修改)。这完全归功于多态--编译器针对虚函数产生了可以在运行时刻确定被调用函数的代码。 1.3 如何“动态联编” 编译器是如何针对虚函数产生可以再运行时刻确定被调用函数的代码呢?也就是说,虚函数实际上是如何被编译器处理的呢?Lippman在深度探索C++对象模型[1]中的不同章节讲到了几种方式,这里把“标准的”方式简单介绍一下。 我所说的“标准”方式,也就是所谓的“VTABLE”机制。编译器发现一个类中有被声明为virtual的函数,就会为其搞一个虚函数表,也就是VTABLE。VTABLE实际上是一个函数指针的数组,每个虚函数占用这个数组的一个slot。一个类只有一个VTABLE,不管它有多少个实例。派生类有自己的VTABLE,但是派生类的VTABLE与基类的VTABLE有相同的函数排列顺序,同名的虚函数被放在两个数组的相同位置上。在创建类实例的时候,编译器还会在每个实例的内存布局中增加一个vptr字段,该字段指向本类的VTABLE。通过这些手段,编译器在看到一个虚函数调用的时候,就会将这个调用改写,针对1.1中的例子: void bar(A * a) { a->foo(); } 会被改写为: void bar(A * a) { (a->vptr[1])(); } 因为派生类和基类的foo()函数具有相同的VTABLE索引,而他们的vptr又指向不同的VTABLE,因此通过这样的方法可以在运行时刻决定调用哪个foo()函数。 虽然实际情况远非这么简单,但是基本原理大致如此。 1.4 overload和override 虚函数总是在派生类中被改写,这种改写被称为“override”。我经常混淆“overload”和“override”这两个单词。但是随着各类C++的书越来越多,后来的程序员也许不会再犯我犯过的错误了。但是我打算澄清一下: override是指派生类重写基类的虚函数,就象我们前面B类中重写了A类中的foo()函数。重写的函数必须有一致的参数表和返回值(C++标准答应返回值不同的情况,这个我会在“语法”部分简单介绍,但是很少编译器支持这个feature)。这个单词好象一直没有什么合适的中文词汇来对应,有人译为“覆盖”,还贴切一些。 overload约定成俗的被翻译为“重载”。是指编写一个与已有函数同名但是参数表不同的函数。例如一个函数即可以接受整型数作为参数,也可以接受浮点数作为参数。 一.简介 虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。假设我们有下面的类层次: class A { public: virtual void foo() { cout << "A::foo() is called" << endl;} }; class B: public A { public: virtual void foo() { cout << "B::foo() is called" << endl;} }; 那么,在使用的时候,我们可以: A * a = new B(); a->foo(); // 在这里,a虽然是指向A的指针,但是被调用的函数(foo)却是B的! 这个例子是虚函数的一个典型应用,通过这个例子,也许你就对虚函数有了一些概念。它虚就虚在所谓“推迟联编”或者“动态联编”上,一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的。由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被成为“虚”函数。 虚函数只能借助于指针或者引用来达到多态的效果,假如是下面这样的代码,则虽然是虚函数,但它不是多态的: class A { public: virtual void foo(); }; class B: public A { virtual void foo(); }; void bar() { A a; a.foo(); // A::foo()被调用 } 1.1 多态 在了解了虚函数的意思之后,再考虑什么是多态就很轻易了。仍然针对上面的类层次,但是使用的方法变的复杂了一些: void bar(A * a) { a->foo(); // 被调用的是A::foo() 还是B::foo()? } 因为foo()是个虚函数,所以在bar这个函数中,只根据这段代码,无从确定这里被调用的是A::foo()还是B::foo(),但是可以肯定的说:假如a指向的是A类的实例,则A::foo()被调用,假如a指向的是B类的实例,则B::foo()被调用。 这种同一代码可以产生不同效果的特点,被称为“多态”。 1.2 多态有什么用? 多态这么神奇,但是能用来做什么呢?这个命题我难以用一两句话概括,一般的C++教程(或者其它面向对象语言的教程)都用一个画图的例子来展示多态的用途,我就不再重复这个例子了,假如你不知道这个例子,随便找本书应该都有介绍。我试图从一个抽象的角度描述一下,回头再结合那个画图的例子,也许你就更轻易理解。 在面向对象的编程中,首先会针对数据进行抽象(确定基类)和继续(确定派生类),构成类层次。这个类层次的使用者在使用它们的时候,假如仍然在需要基类的时候写针对基类的代码,在需要派生类的时候写针对派生类的代码,就等于类层次完全暴露在使用者面前。假如这个类层次有任何的改变(增加了新类),都需要使用者“知道”(针对新类写代码)。这样就增加了类层次与其使用者之间的耦合,有人把这种情况列为程序中的“bad smell”之一。 多态可以使程序员脱离这种窘境。再回头看看1.1中的例子,bar()作为A-B这个类层次的使用者,它并不知道这个类层次中有多少个类,每个类都叫什么,但是一样可以很好的工作,当有一个C类从A类派生出来后,bar()也不需要“知道”(修改)。这完全归功于多态--编译器针对虚函数产生了可以在运行时刻确定被调用函数的代码。 1.3 如何“动态联编” 编译器是如何针对虚函数产生可以再运行时刻确定被调用函数的代码呢?也就是说,虚函数实际上是如何被编译器处理的呢?Lippman在深度探索C++对象模型[1]中的不同章节讲到了几种方式,这里把“标准的”方式简单介绍一下。 我所说的“标准”方式,也就是所谓的“VTABLE”机制。编译器发现一个类中有被声明为virtual的函数,就会为其搞一个虚函数表,也就是VTABLE。VTABLE实际上是一个函数指针的数组,每个虚函数占用这个数组的一个slot。一个类只有一个VTABLE,不管它有多少个实例。派生类有自己的VTABLE,但是派生类的VTABLE与基类的VTABLE有相同的函数排列顺序,同名的虚函数被放在两个数组的相同位置上。在创建类实例的时候,编译器还会在每个实例的内存布局中增加一个vptr字段,该字段指向本类的VTABLE。通过这些手段,编译器在看到一个虚函数调用的时候,就会将这个调用改写,针对1.1中的例子: void bar(A * a) { a->foo(); } 会被改写为: void bar(A * a) { (a->vptr[1])(); } 因为派生类和基类的foo()函数具有相同的VTABLE索引,而他们的vptr又指向不同的VTABLE,因此通过这样的方法可以在运行时刻决定调用哪个foo()函数。 虽然实际情况远非这么简单,但是基本原理大致如此。 1.4 overload和override 虚函数总是在派生类中被改写,这种改写被称为“override”。我经常混淆“overload”和“override”这两个单词。但是随着各类C++的书越来越多,后来的程序员也许不会再犯我犯过的错误了。但是我打算澄清一下: override是指派生类重写基类的虚函数,就象我们前面B类中重写了A类中的foo()函数。重写的函数必须有一致的参数表和返回值(C++标准答应返回值不同的情况,这个我会在“语法”部分简单介绍,但是很少编译器支持这个feature)。这个单词好象一直没有什么合适的中文词汇来对应,有人译为“覆盖”,还贴切一些。 overload约定成俗的被翻译为“重载”。是指编写一个与已有函数同名但是参数表不同的函数。例如一个函数即可以接受整型数作为参数,也可以接受浮点数作为参数。 QQread.com 推出游戏功略 http://www.qqread.com/netgame/game/index.Html 魔兽世界 跑跑卡丁车 街头篮球 水浒Q传 龙与地下城OL 征服 轩辕剑5 FIFA07 热血江湖 大唐风云 梦幻西游 武林外传 一.简介 虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。假设我们有下面的类层次: class A { public: virtual void foo() { cout << "A::foo() is called" << endl;} }; class B: public A { public: virtual void foo() { cout << "B::foo() is called" << endl;} }; 那么,在使用的时候,我们可以: A * a = new B(); a->foo(); // 在这里,a虽然是指向A的指针,但是被调用的函数(foo)却是B的! 这个例子是虚函数的一个典型应用,通过这个例子,也许你就对虚函数有了一些概念。它虚就虚在所谓“推迟联编”或者“动态联编”上,一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的。由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被成为“虚”函数。 虚函数只能借助于指针或者引用来达到多态的效果,假如是下面这样的代码,则虽然是虚函数,但它不是多态的: class A { public: virtual void foo(); }; class B: public A { virtual void foo(); }; void bar() { A a; a.foo(); // A::foo()被调用 } 1.1 多态 在了解了虚函数的意思之后,再考虑什么是多态就很轻易了。仍然针对上面的类层次,但是使用的方法变的复杂了一些: void bar(A * a) { a->foo(); // 被调用的是A::foo() 还是B::foo()? } 因为foo()是个虚函数,所以在bar这个函数中,只根据这段代码,无从确定这里被调用的是A::foo()还是B::foo(),但是可以肯定的说:假如a指向的是A类的实例,则A::foo()被调用,假如a指向的是B类的实例,则B::foo()被调用。 这种同一代码可以产生不同效果的特点,被称为“多态”。 1.2 多态有什么用? 多态这么神奇,但是能用来做什么呢?这个命题我难以用一两句话概括,一般的C++教程(或者其它面向对象语言的教程)都用一个画图的例子来展示多态的用途,我就不再重复这个例子了,假如你不知道这个例子,随便找本书应该都有介绍。我试图从一个抽象的角度描述一下,回头再结合那个画图的例子,也许你就更轻易理解。 在面向对象的编程中,首先会针对数据进行抽象(确定基类)和继续(确定派生类),构成类层次。这个类层次的使用者在使用它们的时候,假如仍然在需要基类的时候写针对基类的代码,在需要派生类的时候写针对派生类的代码,就等于类层次完全暴露在使用者面前。假如这个类层次有任何的改变(增加了新类),都需要使用者“知道”(针对新类写代码)。这样就增加了类层次与其使用者之间的耦合,有人把这种情况列为程序中的“bad smell”之一。 多态可以使程序员脱离这种窘境。再回头看看1.1中的例子,bar()作为A-B这个类层次的使用者,它并不知道这个类层次中有多少个类,每个类都叫什么,但是一样可以很好的工作,当有一个C类从A类派生出来后,bar()也不需要“知道”(修改)。这完全归功于多态--编译器针对虚函数产生了可以在运行时刻确定被调用函数的代码。 1.3 如何“动态联编” 编译器是如何针对虚函数产生可以再运行时刻确定被调用函数的代码呢?也就是说,虚函数实际上是如何被编译器处理的呢?Lippman在深度探索C++对象模型[1]中的不同章节讲到了几种方式,这里把“标准的”方式简单介绍一下。 我所说的“标准”方式,也就是所谓的“VTABLE”机制。编译器发现一个类中有被声明为virtual的函数,就会为其搞一个虚函数表,也就是VTABLE。VTABLE实际上是一个函数指针的数组,每个虚函数占用这个数组的一个slot。一个类只有一个VTABLE,不管它有多少个实例。派生类有自己的VTABLE,但是派生类的VTABLE与基类的VTABLE有相同的函数排列顺序,同名的虚函数被放在两个数组的相同位置上。在创建类实例的时候,编译器还会在每个实例的内存布局中增加一个vptr字段,该字段指向本类的VTABLE。通过这些手段,编译器在看到一个虚函数调用的时候,就会将这个调用改写,针对1.1中的例子: void bar(A * a) { a->foo(); } 会被改写为: void bar(A * a) { (a->vptr[1])(); } 因为派生类和基类的foo()函数具有相同的VTABLE索引,而他们的vptr又指向不同的VTABLE,因此通过这样的方法可以在运行时刻决定调用哪个foo()函数。 虽然实际情况远非这么简单,但是基本原理大致如此。 1.4 overload和override 虚函数总是在派生类中被改写,这种改写被称为“override”。我经常混淆“overload”和“override”这两个单词。但是随着各类C++的书越来越多,后来的程序员也许不会再犯我犯过的错误了。但是我打算澄清一下: override是指派生类重写基类的虚函数,就象我们前面B类中重写了A类中的foo()函数。重写的函数必须有一致的参数表和返回值(C++标准答应返回值不同的情况,这个我会在“语法”部分简单介绍,但是很少编译器支持这个feature)。这个单词好象一直没有什么合适的中文词汇来对应,有人译为“覆盖”,还贴切一些。 overload约定成俗的被翻译为“重载”。是指编写一个与已有函数同名但是参数表不同的函数。例如一个函数即可以接受整型数作为参数,也可以接受浮点数作为参数。 QQread.com 推出游戏功略 http://www.qqread.com/netgame/game/index.html 魔兽世界 跑跑卡丁车 街头篮球 水浒Q传 龙与地下城OL 征服 轩辕剑5 FIFA07 热血江湖 大唐风云 梦幻西游 武林外传 一.简介 虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。假设我们有下面的类层次: class A { public: virtual void foo() { cout << "A::foo() is called" << endl;} }; class B: public A { public: virtual void foo() { cout << "B::foo() is called" << endl;} }; 那么,在使用的时候,我们可以: A * a = new B(); a->foo(); // 在这里,a虽然是指向A的指针,但是被调用的函数(foo)却是B的! 这个例子是虚函数的一个典型应用,通过这个例子,也许你就对虚函数有了一些概念。它虚就虚在所谓“推迟联编”或者“动态联编”上,一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的。由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被成为“虚”函数。 虚函数只能借助于指针或者引用来达到多态的效果,假如是下面这样的代码,则虽然是虚函数,但它不是多态的: class A { public: virtual void foo(); }; class B: public A { virtual void foo(); }; void bar() { A a; a.foo(); // A::foo()被调用 } 1.1 多态 在了解了虚函数的意思之后,再考虑什么是多态就很轻易了。仍然针对上面的类层次,但是使用的方法变的复杂了一些: void bar(A * a) { a->foo(); // 被调用的是A::foo() 还是B::foo()? } 因为foo()是个虚函数,所以在bar这个函数中,只根据这段代码,无从确定这里被调用的是A::foo()还是B::foo(),但是可以肯定的说:假如a指向的是A类的实例,则A::foo()被调用,假如a指向的是B类的实例,则B::foo()被调用。 这种同一代码可以产生不同效果的特点,被称为“多态”。 1.2 多态有什么用? 多态这么神奇,但是能用来做什么呢?这个命题我难以用一两句话概括,一般的C++教程(或者其它面向对象语言的教程)都用一个画图的例子来展示多态的用途,我就不再重复这个例子了,假如你不知道这个例子,随便找本书应该都有介绍。我试图从一个抽象的角度描述一下,回头再结合那个画图的例子,也许你就更轻易理解。 在面向对象的编程中,首先会针对数据进行抽象(确定基类)和继续(确定派生类),构成类层次。这个类层次的使用者在使用它们的时候,假如仍然在需要基类的时候写针对基类的代码,在需要派生类的时候写针对派生类的代码,就等于类层次完全暴露在使用者面前。假如这个类层次有任何的改变(增加了新类),都需要使用者“知道”(针对新类写代码)。这样就增加了类层次与其使用者之间的耦合,有人把这种情况列为程序中的“bad smell”之一。 多态可以使程序员脱离这种窘境。再回头看看1.1中的例子,bar()作为A-B这个类层次的使用者,它并不知道这个类层次中有多少个类,每个类都叫什么,但是一样可以很好的工作,当有一个C类从A类派生出来后,bar()也不需要“知道”(修改)。这完全归功于多态--编译器针对虚函数产生了可以在运行时刻确定被调用函数的代码。 1.3 如何“动态联编” 编译器是如何针对虚函数产生可以再运行时刻确定被调用函数的代码呢?也就是说,虚函数实际上是如何被编译器处理的呢?Lippman在深度探索C++对象模型[1]中的不同章节讲到了几种方式,这里把“标准的”方式简单介绍一下。 我所说的“标准”方式,也就是所谓的“VTABLE”机制。编译器发现一个类中有被声明为virtual的函数,就会为其搞一个虚函数表,也就是VTABLE。VTABLE实际上是一个函数指针的数组,每个虚函数占用这个数组的一个slot。一个类只有一个VTABLE,不管它有多少个实例。派生类有自己的VTABLE,但是派生类的VTABLE与基类的VTABLE有相同的函数排列顺序,同名的虚函数被放在两个数组的相同位置上。在创建类实例的时候,编译器还会在每个实例的内存布局中增加一个vptr字段,该字段指向本类的VTABLE。通过这些手段,编译器在看到一个虚函数调用的时候,就会将这个调用改写,针对1.1中的例子: void bar(A * a) { a->foo(); } 会被改写为: void bar(A * a) { (a->vptr[1])(); } 因为派生类和基类的foo()函数具有相同的VTABLE索引,而他们的vptr又指向不同的VTABLE,因此通过这样的方法可以在运行时刻决定调用哪个foo()函数。 虽然实际情况远非这么简单,但是基本原理大致如此。 1.4 overload和override 虚函数总是在派生类中被改写,这种改写被称为“override”。我经常混淆“overload”和“override”这两个单词。但是随着各类C++的书越来越多,后来的程序员也许不会再犯我犯过的错误了。但是我打算澄清一下: override是指派生类重写基类的虚函数,就象我们前面B类中重写了A类中的foo()函数。重写的函数必须有一致的参数表和返回值(C++标准答应返回值不同的情况,这个我会在“语法”部分简单介绍,但是很少编译器支持这个feature)。这个单词好象一直没有什么合适的中文词汇来对应,有人译为“覆盖”,还贴切一些。 overload约定成俗的被翻译为“重载”。是指编写一个与已有函数同名但是参数表不同的函数。例如一个函数即可以接受整型数作为参数,也可以接受浮点数作为参数。 QQread.com 推出游戏功略 http://www.qqread.com/netgame/game/index.html 魔兽世界 跑跑卡丁车 街头篮球 水浒Q传 龙与地下城OL 征服 轩辕剑5 FIFA07 热血江湖 大唐风云 梦幻西游 武林外传 right"(出处:清风软件下载学院)
󰈣󰈤
日版宠物情人插曲《Winding Road》歌词

日版宠物情人2017的插曲,很带节奏感,日语的,女生唱的。 最后听见是在第8集的时候女主手割伤了,然后男主用嘴帮她吸了一下,插曲就出来了。 歌手:Def...

兄弟共妻,我成了他们夜里的美食

老钟家的两个儿子很特别,就是跟其他的人不太一样,魔一般的执着。兄弟俩都到了要结婚的年龄了,不管自家老爹怎么磨破嘴皮子,兄弟俩说不娶就不娶,老父母为兄弟两操碎了心...

网络安全治理:国家安全保障的主要方向是打击犯罪,而不是处置和惩罚受害者

来源:中国青年报 新的攻击方法不断涌现,黑客几乎永远占据网络攻击的上风,我们不可能通过技术手段杜绝网络攻击。国家安全保障的主要方向是打击犯罪,而不是处置和惩罚...

 
 
 
>>返回首页<<
 为你推荐
 
 
 
 转载本文
 UBB代码 HTML代码
复制到剪贴板...
 
 
 热帖排行
 
单纯美女 迷人女孩
校园甜美少女
忍辱负重
大学校园
 
 
王朝网络微信公众号
微信扫码关注本站公众号wangchaonetcn
 
  免责声明:本文仅代表作者个人观点,与王朝网络无关。王朝网络登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
©2005- 王朝网络 版权所有