青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Benjamin

靜以修身,儉以養(yǎng)德,非澹薄無(wú)以明志,非寧?kù)o無(wú)以致遠(yuǎn)。
隨筆 - 398, 文章 - 0, 評(píng)論 - 196, 引用 - 0
數(shù)據(jù)加載中……

C++之virtual functions(虛函數(shù))實(shí)現(xiàn)細(xì)節(jié)及相關(guān)概念

c++中的(static) type和 (dynamic) type 概念是基于多態(tài)(polymorphism) ,例如:Vehicle*指針如果實(shí)際是指向一個(gè)Car對(duì)象,那么這個(gè)指針的靜態(tài)類型就是Vechicle,Car則是他的動(dòng)態(tài)類型。靜態(tài)類型發(fā)生在編譯器編譯時(shí),動(dòng)態(tài)類型發(fā)生在動(dòng)態(tài)綁定時(shí)。
我們常說(shuō)的override(覆蓋)就是針對(duì)虛函數(shù)而言。
對(duì)虛函數(shù)的實(shí)現(xiàn)應(yīng)該說(shuō)各個(gè)編譯器是不一樣的,大多數(shù)的編譯器是這樣的:
為每一個(gè)有虛函數(shù)的類增加一個(gè)虛表,這個(gè)虛表是靜態(tài)的,還有一個(gè)虛指針,為每個(gè)類對(duì)象。例如:
// Your original C++ source code
 class Base {
 public:
   virtual arbitrary_return_type virt0(...arbitrary params...);
   virtual arbitrary_return_type virt1(...arbitrary params...);
   virtual arbitrary_return_type virt2(...arbitrary params...);
   virtual arbitrary_return_type virt3(...arbitrary params...);
   virtual arbitrary_return_type virt4(...arbitrary params...);
   ...
 };
1 編譯器會(huì)為這個(gè)類的虛函數(shù)添加一個(gè)虛表,類似下面的:
// Pseudo-code (not C++, not C) for a static table defined within file Base.cpp
 
 // Pretend FunctionPtr is a generic pointer to a generic member function
 // (Remember: this is pseudo-code, not C++ code)
 FunctionPtr Base::__vtable[5] = {
   &Base::virt0, &Base::virt1, &Base::virt2, &Base::virt3, &Base::virt4
 };

2 然后增加一個(gè)指向虛表的指針為每一個(gè)類對(duì)象,這個(gè)指針是隱藏的
 // Your original C++ source code
 
 class Base {
 public:
   ...
   FunctionPtr* __vptr;  ← supplied by the compiler, hidden from the programmer
   ...
 };
3 編譯器在構(gòu)造中初始化這個(gè)指針
Base::Base(...arbitrary params...)
   : __vptr(&Base::__vtable[0])  ← supplied by the compiler, hidden from the programmer
   ...
 {
   ...
 }
在派生類中,它也會(huì)增加一個(gè)隱藏的虛表,但是它可以overrides基類的虛函數(shù)如:
// Pseudo-code (not C++, not C) for a static table defined within file Der.cpp
 
 // Pretend FunctionPtr is a generic pointer to a generic member function
 // (Remember: this is pseudo-code, not C++ code)
 FunctionPtr Der::__vtable[5] = {
   &Der::virt0, &Der::virt1, &Der::virt2, &Base::virt3, &Base::virt4
 };    

最后看看底層是如何調(diào)用的如:                                  
void mycode(Base* p)
 {
   p->virt3();
 }
主要三部分:
1.獲取隱藏的指向虛表的指針,并把它放在 register中如r1;
2.獲取指針r2=r1+3*4(假定一個(gè)指針有四個(gè)字節(jié)) ,并把它放到register中。
3 根據(jù)r2的地址調(diào)用函數(shù)。

所以說(shuō),調(diào)用一個(gè)虛函數(shù)至少和非虛函數(shù)差不多.
在這里我們可以看出一個(gè)虛指針的長(zhǎng)度,至少是四個(gè)字節(jié),但是要注意編譯器對(duì)它的具體實(shí)現(xiàn)

純虛函數(shù)怎樣用,下面的例子可以說(shuō)明這個(gè)問(wèn)題。
象下面的代碼就可以用純虛函數(shù)來(lái)實(shí)現(xiàn):
typedef std::vector<Vehicle*>  VehicleList;
 
 void myCode(VehicleList& v)
 {
   for (VehicleList::iterator p = v.begin(); p != v.end(); ++p) {
     Vehicle& v = **p;  // just for shorthand
 
     // generic code that works for any vehicle...
     ...
 
     // perform the "foo-bar" operation.
     // note: the details of the "foo-bar" operation depend
     // on whether we're working with a car or a truck.
     if (v is a Car) {
       // car-specific code that does "foo-bar" on car v
       ...
     } else if (v is a Truck) {
       // truck-specific code that does "foo-bar" on truck v
       ...
     } else {
       // semi-generic code that does "foo-bar" on something else
       ...
     }
 
     // generic code that works for any vehicle...
     ...
   }
 }
用純虛函數(shù)實(shí)現(xiàn)如下:
class Vehicle {
 public:
   // performs the "foo-bar" operation
   virtual void fooBar() = 0;
 };
typedef std::vector<Vehicle*>  VehicleList;
 
 void myCode(VehicleList& v)
 {
   for (VehicleList::iterator p = v.begin(); p != v.end(); ++p) {
     Vehicle& v = **p;  // just for shorthand
 
     // generic code that works for any vehicle...
     ...
 
     // perform the "foo-bar" operation.
     v.fooBar();
 
     // generic code that works for any vehicle...
     ...
   }
 }

也可以用繼承的方法來(lái)實(shí)現(xiàn)
class Car : public Vehicle {
 public:
   virtual void fooBar();
 };
 
 void Car::fooBar()
 {
   // car-specific code that does "foo-bar" on 'this'
   ...  ← this is the code that was in {...} of if (v is a Car)
 }
 
 class Truck : public Vehicle {
 public:
   virtual void fooBar();
 };
 
 void Truck::fooBar()
 {
   // truck-specific code that does "foo-bar" on 'this'
   ...  ← this is the code that was in {...} of if (v is a Truck)
 }
有純虛函數(shù)的是抽象基類,強(qiáng)迫派生類接受基類的接口并實(shí)現(xiàn),在COM(組件)中比較常見(jiàn),。

virtual constructor(虛構(gòu)造)的一個(gè)實(shí)現(xiàn)方法之一:
class Shape {
 public:
   virtual ~Shape() { }                 // A virtual destructor
   virtual void draw() = 0;             // A pure virtual function
   virtual void move() = 0;
   ...
   virtual Shape* clone()  const = 0;   // Uses the copy constructor
   virtual Shape* create() const = 0;   // Uses the default constructor
 };
 
 class Circle : public Shape {
 public:
   Circle* clone()  const;   // Covariant Return Types; see below
   Circle* create() const;   // Covariant Return Types; see below
   ...
 };
 
 Circle* Circle::clone()  const { return new Circle(*this); }
 Circle* Circle::create() const { return new Circle();      }

void userCode(Shape& s)
 {
   Shape* s2 = s.clone();
   Shape* s3 = s.create();
   ...
   delete s2;    // You need a virtual destructor here
   delete s3;
 }
注意在VC6中必須寫(xiě)成Shape*,VC7就不用改,支持返回類型可以變。

posted on 2009-06-13 17:38 Benjamin 閱讀(2495) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C/C++

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久一二三| 欧美成在线观看| av成人免费观看| 亚洲日本成人| 久久久国产亚洲精品| 中文无字幕一区二区三区| 9色porny自拍视频一区二区| 在线亚洲国产精品网站| 亚洲自拍高清| 性伦欧美刺激片在线观看| 欧美一区二区视频在线观看2020| 亚洲免费一在线| 久久激情五月婷婷| 久久美女性网| 欧美日韩激情网| 国产精品久久久久毛片软件| 国产嫩草影院久久久久| 一区二区在线观看视频| 亚洲福利专区| 亚洲视频精选在线| 久久久久久久综合色一本| 欧美国产日本高清在线| 日韩一级在线观看| 欧美在线地址| 欧美激情一二三区| 国产精品永久免费在线| 亚洲国产精品久久久久婷婷老年| 亚洲精品日韩久久| 久久岛国电影| 91久久国产综合久久91精品网站| 欧美激情按摩| 亚欧成人精品| 欧美日韩国产a| 国一区二区在线观看| 日韩手机在线导航| 久久精品水蜜桃av综合天堂| 亚洲另类视频| 老司机午夜精品| 国产欧美一区二区视频| 99re6这里只有精品| 久久在线播放| 一本色道久久99精品综合| 久久午夜色播影院免费高清| 国产精品国色综合久久| 亚洲清纯自拍| 蜜桃视频一区| 香蕉久久夜色精品| 亚洲黄一区二区三区| 亚洲男女自偷自拍图片另类| 欧美大片在线观看一区| 狠狠色综合色综合网络| 亚洲欧美国产高清| 亚洲欧洲一区二区三区在线观看| 欧美一级大片在线观看| 国产精品永久免费| 亚洲一品av免费观看| 亚洲欧洲久久| 美女脱光内衣内裤视频久久影院 | 亚洲性视频网站| 欧美国产高潮xxxx1819| 亚洲黄色小视频| 欧美成人综合在线| 久久午夜羞羞影院免费观看| 精品成人久久| 久久这里只有精品视频首页| 亚洲欧美在线播放| 国产一区二区欧美| 欧美诱惑福利视频| 欧美一区二区三区久久精品| 国产亚洲福利| 久久久久国产一区二区三区| 午夜精品一区二区三区在线| 国产欧美不卡| 久久亚洲免费| 能在线观看的日韩av| 最新日韩在线视频| 亚洲欧洲日韩综合二区| 欧美日韩三级| 亚洲欧美网站| 午夜精品一区二区三区在线播放| 国产一区二区成人久久免费影院| 久久九九国产精品| 久久久久网址| 亚洲日本va午夜在线电影| 亚洲国产精品黑人久久久| 欧美激情一区二区在线| 榴莲视频成人在线观看| 99精品国产99久久久久久福利| 91久久香蕉国产日韩欧美9色| 欧美国产高清| 欧美一区三区三区高中清蜜桃| 欧美一区二区三区精品| 亚洲成在线观看| 宅男精品导航| 国产精品美女久久久| 久久久国产亚洲精品| 免费成人高清视频| 亚洲一区二区在线播放| 久久国产黑丝| 夜夜精品视频| 欧美一站二站| 一区二区三区免费网站| 性欧美1819sex性高清| 亚洲激情成人| 亚洲在线第一页| 亚洲成人在线视频播放| 99国产精品久久久| 久久久久99| 一区二区三区欧美在线观看| 午夜精品一区二区三区在线| 最新国产乱人伦偷精品免费网站 | 欧美日韩亚洲另类| 久久免费视频网站| 欧美性感一类影片在线播放| 久久在线观看视频| 国产精品香蕉在线观看| 欧美激情一区二区三级高清视频| 国产乱码精品一区二区三区av | 欧美高清在线观看| 国产精品入口尤物| 亚洲人成网站777色婷婷| 国产一区二区三区四区五区美女| 亚洲人成精品久久久久| 亚洲狠狠丁香婷婷综合久久久| 亚洲欧美综合网| 亚洲小说区图片区| 欧美国产成人精品| 欧美国产三区| 精品88久久久久88久久久| 亚洲欧美日韩天堂| 亚洲免费一级电影| 国产精品久久久久av| 亚洲精品美女久久久久| 亚洲国产精品一区二区久| 欧美在线短视频| 久久本道综合色狠狠五月| 国产精品成人免费精品自在线观看 | 欧美日韩综合| 最新中文字幕一区二区三区| 亚洲国产精品传媒在线观看 | 亚洲电影成人| 在线观看亚洲一区| 久久精品国产96久久久香蕉| 欧美在线高清视频| 国产伦精品一区二区三| 亚洲欧美另类国产| 欧美在线三区| 国产情侣一区| 午夜精品网站| 欧美成人激情在线| 亚洲国产精品成人一区二区| 麻豆精品精品国产自在97香蕉| 乱人伦精品视频在线观看| 亚洲高清av在线| 欧美激情中文字幕在线| 日韩视频一区二区三区| 亚洲综合精品四区| 国产深夜精品福利| 巨胸喷奶水www久久久免费动漫| 欧美成人免费在线观看| 一本久道久久久| 国产精品免费一区二区三区在线观看 | 亚洲精品日韩激情在线电影| 久久精品一区二区三区中文字幕 | 亚洲第一精品福利| 久久人人精品| 亚洲欧洲精品成人久久奇米网| 亚洲视频在线一区观看| 国产精品亚洲精品| 久久婷婷综合激情| 一区二区国产在线观看| 久久久精品久久久久| 亚洲国产小视频| 国产精品jvid在线观看蜜臀| 欧美一区日本一区韩国一区| 亚洲国产精品电影在线观看| 欧美一区综合| 亚洲狼人精品一区二区三区| 国产精品久久中文| 欧美xx69| 久久黄色级2电影| 一本久久综合亚洲鲁鲁| 可以免费看不卡的av网站| 亚洲视频观看| 亚洲国产精品一区二区www| 国产精品久久久久毛片软件| 老司机一区二区| 先锋影音国产一区| 亚洲三级视频在线观看| 久热综合在线亚洲精品| 亚洲欧美久久| 夜夜嗨一区二区| 亚洲电影天堂av| 国产乱码精品一区二区三区不卡 | 欧美视频在线不卡| 乱人伦精品视频在线观看| 午夜电影亚洲| 亚洲午夜精品视频| 99热在线精品观看| 亚洲国产日日夜夜|