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

山寨:不是最好的,是最適合我們的!歡迎體驗山寨 中文版MSDN

Blog @ Blog

當華美的葉片落盡,生命的脈絡才歷歷可見。 -- 聶魯達

常用鏈接

統計

積分與排名

BBS

Blog

Web

最新評論

C++中的虛函數(一)

轉自:http://www.vckbase.com/document/viewdoc/?id=950

C++中的虛函數(一)


作者:aber




    雖然很難找到一本不討論多態性的C++書籍或雜志,但是,大多數這類討論使多態性和C++虛函數的使用看起來很難。我打算在這篇文章中通過從幾個方面和結合一些例子使讀者理解在C++中的虛函數實現技術。說明一點,寫這篇文章只是想和大家交流學習經驗因為本人學識淺薄,難免有一些錯誤和不足,希望大家批評和指正,在此深表感謝!

一、 基本概念
    首先,C++通過虛函數實現多態."無論發送消息的對象屬于什么類,它們均發送具有同一形式的消息,對消息的處理方式可能隨接手消息的對象而變"的處理方式被稱為多態性。"在某個基類上建立起來的類的層次構造中,可以對任何一個派生類的對象中的同名過程進行調用,而被調用的過程提供的處理可以隨其所屬的類而變。"虛函數首先是一種成員函數,它可以在該類的派生類中被重新定義并被賦予另外一種處理功能。

二、 虛函數的定義與派生類中的重定義

class 類名{
public:
virtual 成員函數說明;
}
class 類名:基類名{
public:
virtual 成員函數說明;
}
三、 虛函數在內存中的結構

1.我們先看一個例子:
#include "iostream.h"
#include "string.h"
class A {
public:
virtual void fun0() { cout << "A::fun0" << endl; }
};
int main(int argc, char* argv[])
{
A  a;
cout << "Size of A = " << sizeof(a) << endl;
return 0;
}      
結果如下:Size of A = 4

2.如果再添加一個虛函數:virtual void fun1() { cout << "A::fun" << endl;}
得到相同的結果。如果去掉函數前面的virtual修飾符
class A {
public:
void fun0() { cout << "A::fun0" << endl; }
};
int main(int argc, char* argv[])
{
A  a;
cout << "Size of A = " << sizeof(a) << endl;
return 0;
}      
結果如下:Size of A = 1
 
3.在看下面的結果:
class A {
public:
virtual void fun0() { cout << "A::fun0" << endl; }
int a;
int b;
};
int main(int argc, char* argv[])
{
A  a;
cout << "Size of A = " << sizeof(a) << endl;
return 0;
}      
結果如下:Size of A = 12

其實虛函數在內存中結構是這樣的:


圖一

    在window2000下指針在內存中占4個字節,虛函數在一個虛函數表(VTABLE)中保存函數地址。在看下面例子。
class A {
public:
virtual void fun0() { cout << "A::fun0" << endl; }
virtual void fun1() { cout << "A::fun1" << endl; }
int a;
int b;
};
int main(int argc, char* argv[])
{
A  a;
cout << "Size of A = " << sizeof(a) << endl;
return 0;
}
結果如下:結果如下:
Size of A = 4

    虛函數的內存結構如下,你也可以通過函數指針,先找到虛函數表(VTABLE),然后訪問每個函數地址來驗證這種結構,在國外網站作者是:Zeeshan Amjad寫的"ATL on the Hood中有詳細介紹"


圖二

4.我們再來看看繼承中虛函數的內存結構,先看下面的例子
class A {
public:
virtual void f() { }
};
class B {
public:
virtual void f() { }
};
class C {
public:
virtual void f() { }
};
class Drive : public A, public B, public C {
};
int main() {
Drive d;
cout << "Size is = " << sizeof(d) << endl;
return 0;
}      
結果如下:Size is = 12 ,相信大家一看下面的結構圖就會很清楚,


圖三

5.我們再來看看用虛函數實現多態性,先看個例子:
class A {
public:
virtual void f() { cout << "A::f" << endl; }
};
class B :public A{
public:
virtual void f() { cout << "B::f" << endl;}
};
class C :public A {
public:
virtual void f() { cout << "C::f" << endl;}
};
class Drive : public C {
public:
virtual void f() { cout << "D::f" << endl;}
};
int main(int argc, char* argv[])
{
A a;
B b;
C c;
Drive d;
a.f();
b.f();
c.f();
d.f();
return 0;
}
結果:A::f
B::f
C::f
D::f
不用解釋,相信大家一看就明白什么道理!注意:多態不是函數重載

6.用虛函數實現動態連接在編譯期間,C++編譯器根據程序傳遞給函數的參數或者函數返回類型來決定程序使用那個函數,然后編譯器用正確的的函數替換每次啟動。這種基于編譯器的替換被稱為靜態連接,他們在程序運行之前執行。另一方面,當程序執行多態性時,替換是在程序執行期進行的,這種運行期間替換被稱為動態連接。如下例子:
class A{
public:
virtual void f(){cout << "A::f" << endl;};
};
class B:public A{
public:
virtual void f(){cout << "B::f" << endl;};
};
class C:public A{
public:
virtual void f(){cout << "C::f" << endl;};
};
void test(A *a){
a->f();
};
int main(int argc, char* argv[])
{
B *b=new B;
C *c=new C;
char choice;
do{
cout<<"type  B for class B,C for class C:"<<endl;
cin>>choice;
if(choice==''b'')
test(b);
else if(choice==''c'')
test(c);
}while(1);
cout<<endl<<endl;
return 0;
}
    在上面的例子中,如果把類A,B,C中的virtual修飾符去掉,看看打印的結果,然后再看下面一個例子想想兩者的聯系。如果把B和C中的virtual修飾符去掉,又會怎樣,結果和沒有去掉一樣。

7.在基類中調用繼承類的函數(如果此函數是虛函數才能如此)還是先看例子:
class A {
public:
virtual void fun() {
cout << "A::fun" << endl;
}
void show() {
fun();
}
};
class B : public A {
public:
virtual void fun() {
cout << "B::fun" << endl;
}
};
int main() {
A a;
a.show();
return 0;
}      
打印結果:A::fun

    在6中的例子中,test(A *a)其實有一個繼承類指針向基類指針隱式轉化的過程。可以看出利用虛函數我們可以在基類調用繼承類函數。但如果不是虛函數,繼承類指針轉化為基類指針后只可以調用基類函數。反之,如果基類指針向繼承類指針轉化的情況怎樣,這只能進行顯示轉化,轉化后的繼承類指針可以調用基類和繼承類指針。如下例子:
class A {
public:
void fun() {
cout << "A::fun" << endl;
}
};
class B : public A {
public:
void fun() {
cout << "B::fun" << endl;
}
void fun0() {
cout << "B::fun0" << endl;
}
};
int main() {
A *a=new A;
B *b=new B;
A *pa;
B *pb;
pb=static_cast<B *>(a); //基類指針向繼承類指針進行顯示轉化
pb->fun0();
pb->fun();
return 0;
}  
參考資料:
1.科學出版社 《C++程序設計》
2.Zeeshan Amjad 《ATL on the Hood》

posted on 2008-04-10 17:55 isabc 閱讀(232) 評論(0)  編輯 收藏 引用

廣告信息(免費廣告聯系)

中文版MSDN:
歡迎體驗

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国产精品区一区| 亚洲精品美女久久久久| 久久久久国产一区二区三区| 免费一级欧美在线大片| 亚洲免费视频观看| 亚洲精品一区二区三区不| 韩日欧美一区| 亚洲大胆女人| 一本大道久久精品懂色aⅴ| 99re在线精品| 亚洲欧美另类在线观看| 久久免费高清视频| 亚洲二区视频在线| 中国成人黄色视屏| 亚洲综合色婷婷| 亚洲第一中文字幕| 亚洲视频www| 老鸭窝亚洲一区二区三区| 亚洲福利在线视频| 久久精品中文| 国产欧美精品久久| 99精品热6080yy久久| 久久夜色精品国产噜噜av| 日韩午夜av在线| 久久午夜影视| av成人免费| 麻豆精品在线播放| 欧美日韩一区视频| 亚洲啪啪91| 亚洲一区亚洲二区| 欧美电影免费观看| 欧美亚洲网站| 国产麻豆视频精品| 亚洲综合色在线| 中文av字幕一区| 国产精品一区亚洲| 亚洲欧美伊人| 午夜精品美女久久久久av福利| 久久先锋影音av| 9久草视频在线视频精品| 亚洲三级影院| 国产精品久久久久久久久久久久久| 亚洲深夜影院| 午夜精品国产精品大乳美女| 国产精品亚洲аv天堂网| 欧美在线观看一区二区| 欧美一级片一区| 亚洲精品久久久久| 欧美四级电影网站| 久久性色av| 欧美日韩国产不卡在线看| 亚洲男人的天堂在线| 久久精品国产v日韩v亚洲| 国产美女精品一区二区三区| 久久精品亚洲一区二区三区浴池 | 国产欧美精品在线| 免费成人高清| 欧美www视频| 欧美日韩精品免费在线观看视频| 午夜在线精品偷拍| 免费国产一区二区| 欧美一级日韩一级| 欧美精品一区二区三| 久久久久国产精品午夜一区| 欧美激情第3页| 亚洲国产日韩一区| 精品不卡一区| 久久久五月天| 欧美成人免费全部| 亚洲大黄网站| 欧美一区二区三区免费视频| 亚洲男人第一网站| 欧美理论片在线观看| 亚洲国产高清一区二区三区| 在线观看视频免费一区二区三区| 午夜精品短视频| 久久夜色精品国产欧美乱极品 | 黄色精品网站| 亚洲欧洲av一区二区| 欧美一区二区三区免费在线看 | 久久超碰97人人做人人爱| 亚洲午夜激情在线| 国产精品综合av一区二区国产馆| 午夜精品理论片| 久久综合久久美利坚合众国| 亚洲国产小视频在线观看| 欧美不卡视频一区| 亚洲特级毛片| 欧美国产激情| 亚洲欧美日韩一区在线| 国产欧美精品日韩| 亚洲无玛一区| 妖精视频成人观看www| 亚洲精品久久久久久久久久久久久| 欧美激情成人在线视频| 午夜精品久久久久久久久久久久| 久久爱另类一区二区小说| 91久久久精品| 亚洲一区二区免费视频| 在线不卡视频| 中日韩在线视频| 亚洲国产精品一区二区www| 亚洲精品资源| 一区二区三区中文在线观看 | 久久久噜噜噜久久中文字免| 亚洲理论在线观看| 欧美专区一区二区三区| 宅男精品导航| 免费成人性网站| 久久国产精品99精品国产| 欧美日本高清一区| 欧美大片免费| 韩国欧美一区| 亚洲欧美精品suv| 一区二区久久| 欧美高清视频一区二区三区在线观看| 午夜精品久久久久久久久久久久久| 久久精品国产精品亚洲综合| 久久亚洲精品一区二区| 欧美一区二区三区在线播放| 欧美伦理视频网站| 亚洲高清不卡在线| 一区精品在线| 欧美主播一区二区三区| 午夜精品久久久久久久久久久久久 | 99re视频这里只有精品| 可以看av的网站久久看| 久久视频在线视频| 国内精品久久久久影院薰衣草| 亚洲一品av免费观看| 亚洲一区中文| 国产精品九九久久久久久久| 亚洲乱码日产精品bd| av不卡在线观看| 欧美日韩国产美| 日韩视频免费观看高清完整版| 亚洲日本成人网| 欧美精品一级| 一级日韩一区在线观看| 亚洲尤物视频在线| 国产精品毛片va一区二区三区| 一区二区三区四区五区视频 | 亚洲午夜一区二区三区| 亚洲高清精品中出| 午夜天堂精品久久久久| 午夜电影亚洲| 国产日韩欧美中文在线播放| 欧美亚洲免费高清在线观看| 久久成人这里只有精品| 国产综合激情| 久久手机免费观看| 亚洲国产欧美在线| 亚洲综合成人婷婷小说| 国产日韩成人精品| 久久久国产精品一区| 亚洲国产高清一区| 亚洲欧美韩国| 国产一区二区三区av电影| 久久久久五月天| 亚洲区中文字幕| 性做久久久久久久免费看| 好看的av在线不卡观看| 免费日韩视频| 亚洲影院在线| 欧美激情2020午夜免费观看| 中文一区在线| 一区二区在线观看视频在线观看| 欧美成人一区在线| 亚洲你懂的在线视频| 欧美国产视频在线| 先锋影音久久| 亚洲日本va在线观看| 国产精品视频网| 男女激情久久| 午夜久久电影网| 亚洲人成毛片在线播放| 久久精品夜夜夜夜久久| 一本久久综合| 亚洲第一视频网站| 国产乱码精品| 欧美日韩小视频| 久久久亚洲午夜电影| 中日韩高清电影网| 91久久综合亚洲鲁鲁五月天| 欧美精品一区二区三区蜜桃 | 欧美一区日本一区韩国一区| 91久久精品网| 韩国在线视频一区| 国产精品国产三级国产专播品爱网| 久久精品夜色噜噜亚洲a∨| 亚洲美女在线一区| 欧美成ee人免费视频| 欧美亚洲免费| 亚洲婷婷免费| 亚洲精品美女在线观看播放| 韩国av一区二区| 国产欧美一区二区三区另类精品| 欧美理论在线| 欧美区国产区| 欧美激情久久久久|