亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁(yè) > 編程 > C++ > 正文

C++ COM編程之接口背后的虛函數(shù)表

2020-05-23 14:21:08
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
這篇文章主要介紹了C++ COM編程之接口背后的虛函數(shù)表,COM的背后,就是接口,而接口的背后,就是虛函數(shù)表,需要的朋友可以參考下
 
 

前言

學(xué)習(xí)C++的人,肯定都知道多態(tài)機(jī)制;多態(tài)就是用父類型別的指針指向其子類的實(shí)例,然后通過(guò)父類的指針調(diào)用實(shí)際子類的成員函數(shù)。對(duì)于多態(tài)機(jī)制是如何實(shí)現(xiàn)的,你有沒(méi)有想過(guò)呢?而COM中的接口就將這一機(jī)制運(yùn)用到了極致,所以,不知道多態(tài)機(jī)制的人,是永運(yùn)無(wú)法明白COM的。所以,在總結(jié)COM時(shí),是非常有必要專門總結(jié)一下C++的多態(tài)機(jī)制是如何實(shí)現(xiàn)的。

多態(tài)

什么是多態(tài)?上面也說(shuō)了,多態(tài)就是用父類型別的指針指向其子類的實(shí)例,然后通過(guò)父類的指針調(diào)用實(shí)際子類的成員函數(shù)?,F(xiàn)在通過(guò)代碼,讓大家切身的體會(huì)一下多態(tài):

復(fù)制代碼代碼如下:

#include <iostream>
using namespace std;
 
class A
{
public:
    void Print()
    {
        cout<<"I am A."<<endl;
    }
};
 
class B : public A
{
public:
    void Print()
    {
        cout<<"I am B."<<endl;
    }
};
 
int main()
{
    A *pAObj = new B();
    pAObj->Print();
}

 

上面代碼的運(yùn)行結(jié)果是:I am A.這不是多態(tài)的行為。

好了,經(jīng)過(guò)對(duì)上面代碼的改造,就在A類的Print函數(shù)前面加入關(guān)鍵字virtual,具體代碼如下:

復(fù)制代碼代碼如下:

#include <iostream>
using namespace std;
 
class A
{
public:
    virtual void Print()
    {
        cout<<"I am A."<<endl;
    }
};
 
class B : public A
{
public:
    void Print()
    {
        cout<<"I am B."<<endl;
    }
};
 
int main()
{
    A *pAObj = new B();
    pAObj->Print();
}

 

此時(shí),代碼的運(yùn)行結(jié)果為:I am B.這個(gè)時(shí)候就表現(xiàn)出來(lái)了多態(tài)行為。好了,多了我也不說(shuō)了,就通過(guò)這個(gè)簡(jiǎn)單的例子,你就能體會(huì)到多態(tài)的概念了。從下面才開(kāi)始今天的主題。

虛函數(shù)表

多態(tài)機(jī)制的關(guān)鍵就是在于虛函數(shù)表,也就是vtbl。當(dāng)我們定義一個(gè)類,類中包含虛函數(shù)時(shí),其實(shí)也就定義了一張?zhí)摵瘮?shù)表,沒(méi)有虛函數(shù)的類是不包含虛函數(shù)表的,只有該類被實(shí)例化時(shí),才會(huì)將這個(gè)表分配到這個(gè)實(shí)例的內(nèi)存中;在這張?zhí)摵瘮?shù)表中,存放了每個(gè)虛函數(shù)的地址;它就像一個(gè)地圖一樣,指明了實(shí)際所應(yīng)該調(diào)用的函數(shù)。比如我定義一個(gè)類,如下:

 

復(fù)制代碼代碼如下:

class CIF
{
public:
     CIF(){}
     CIF(int i, int f) : m_iVar(i), m_fVar(f){}
     virtual void IF1() { cout<<"I'm IF1"<<endl; }
     virtual void IF2() { cout<<"I'm IF2"<<endl; }
     virtual void IF3() { cout<<"I'm IF3"<<endl; }
     void MemFunc(){ cout<<"I'm IF4"<<endl; }
private:
     int m_iVar;
     float m_fVar;
};

 

這樣的一個(gè)類,當(dāng)你去定義這個(gè)類的實(shí)例時(shí),編譯器會(huì)給這個(gè)類分配一個(gè)成員變量,該變量指向這個(gè)虛函數(shù)表,這個(gè)虛函數(shù)表中的每一項(xiàng)都會(huì)記錄對(duì)應(yīng)的虛函數(shù)的地址;如下圖:

C++ COM編程之接口背后的虛函數(shù)表

這個(gè)類的變量還沒(méi)有被初始化時(shí),就像上圖那樣,變量的值都是隨機(jī)值,而指向虛擬函數(shù)表的指針__vfptr中對(duì)應(yīng)的虛函數(shù)地址也是錯(cuò)誤的地址;只有等我們真正的完成了這個(gè)變量的聲明和初始化時(shí),這些值才能被正確的初始化,如下圖:

C++ COM編程之接口背后的虛函數(shù)表

從上圖中就可以看到,初始化完成以后,指向虛函數(shù)表的__vfptr指針中的元素都被賦予了正確的虛函數(shù)值,分別指向了在類中定義的三個(gè)虛函數(shù)。也看到了,__vfptr指針定義的位置也比m_iVar和m_fVar變量的位置靠前;在C++編譯器中,它保證虛函數(shù)表的指針存在于對(duì)象實(shí)例中最前面的位置,這主要是為了在多層繼承或是多重繼承的情況下,能以高性能取到這張?zhí)摵瘮?shù)表,然后進(jìn)行遍歷,查找對(duì)應(yīng)的虛函數(shù)指針,進(jìn)行對(duì)應(yīng)的調(diào)用。

我們都知道,虛函數(shù)是用來(lái)支持C++中的多態(tài)的,而單獨(dú)的一個(gè)類,有了虛函數(shù),而沒(méi)有任何繼承關(guān)系,也就是說(shuō)沒(méi)有子類去覆蓋父類的虛函數(shù),這樣是毫無(wú)意義的。所以下面就要從各個(gè)方面進(jìn)行詳細(xì)的說(shuō)明虛函數(shù)表。

沒(méi)有實(shí)現(xiàn)多態(tài)的單繼承

比如有如下的繼承關(guān)系:

C++ COM編程之接口背后的虛函數(shù)表

在這個(gè)繼承關(guān)系中,CIF2作為CIF1的子類,但是CIF2沒(méi)有重寫CIF1類的任何虛函數(shù);定義CIF2 if2Obj;實(shí)例,在派生類的實(shí)例中,它的虛函數(shù)表應(yīng)該是像下面這樣的:

復(fù)制代碼代碼如下:

[0]     0x011513c5 {InterfaceDemo2.exe!CIF1::IF1(void)}     void * 
[1]     0x011512cb {InterfaceDemo2.exe!CIF1::IF2(void)}     void * 
[2]     0x01151343 {InterfaceDemo2.exe!CIF1::IF3(void)}     void * 
[3]     0x01151249 {InterfaceDemo2.exe!CIF2::IF4(void)}     void * 
[4]     0x01151433 {InterfaceDemo2.exe!CIF2::IF5(void)}     void * 
[5]     0x01151267 {InterfaceDemo2.exe!CIF2::IF6(void)}     void * 
[6]     0x00000000     void *

 

可以發(fā)現(xiàn),虛函數(shù)按照其聲明順序存放在表中,父類的虛函數(shù)在子類的虛函數(shù)前面。

實(shí)現(xiàn)多態(tài)的單繼承

現(xiàn)在我在CIF2類中,重寫CIF1類的IF1函數(shù),它們的關(guān)系如下:

C++ COM編程之接口背后的虛函數(shù)表

在上圖中,CIF2繼承了CIF1,并且在CIF2類中重寫了CIF1的虛函數(shù)IF1,那我們現(xiàn)在看看虛函數(shù)表是什么樣子的?

 

復(fù)制代碼代碼如下:

[0]     0x00b61311 {InterfaceDemo2.exe!CIF2::IF1(void)}     void * 
[1]     0x00b612c6 {InterfaceDemo2.exe!CIF1::IF2(void)}     void * 
[2]     0x00b61343 {InterfaceDemo2.exe!CIF1::IF3(void)}     void * 
[3]     0x00b61249 {InterfaceDemo2.exe!CIF2::IF4(void)}     void * 
[4]     0x00b61433 {InterfaceDemo2.exe!CIF2::IF5(void)}     void *
[5]     0x00000000     void *

 

你發(fā)現(xiàn)了什么?虛函數(shù)表中的第一項(xiàng)是CIF2::IF1,而不是CIF1::IF1,這說(shuō)明了當(dāng)在子類中重寫父類的虛函數(shù)時(shí),新的函數(shù)的地址覆蓋了父類的虛函數(shù)地址,這樣就能在多態(tài)時(shí)能正確的找到需要被調(diào)用的函數(shù);而沒(méi)有被覆蓋的函數(shù)還是那樣的順序在虛函數(shù)表中存儲(chǔ)著。

沒(méi)有實(shí)現(xiàn)多態(tài)的多繼承

對(duì)于簡(jiǎn)單的,沒(méi)有實(shí)現(xiàn)多態(tài)的多繼承,比如,有下面的一個(gè)多繼承關(guān)系:

C++ COM編程之接口背后的虛函數(shù)表

在子類中沒(méi)有重寫任何父類的虛函數(shù),那么它的虛函數(shù)表應(yīng)該是什么樣子呢?

虛函數(shù)表CIF1,如下:

復(fù)制代碼代碼如下:

[0]     0x001e13d9 {InterfaceDemo2.exe!CIF1::IF1(void)}     void * 
[1]     0x001e12df {InterfaceDemo2.exe!CIF1::IF2(void)}     void * 
[2]     0x001e1357 {InterfaceDemo2.exe!CIF1::IF3(void)}     void * 
[3]     0x001e10c8 {InterfaceDemo2.exe!CIF3::IF4(void)}     void * 
[4]     0x001e1041 {InterfaceDemo2.exe!CIF3::IF5(void)}     void * 
[5]     0x001e1249 {InterfaceDemo2.exe!CIF3::IF6(void)}     void * 
[6]     0x00000000     void *

 

虛函數(shù)表CIF2,如下:

 

復(fù)制代碼代碼如下:

[0]     0x001e1258 {InterfaceDemo2.exe!CIF2::IF7(void)}     void * 
[1]     0x001e1447 {InterfaceDemo2.exe!CIF2::IF8(void)}     void * 
[2]     0x001e127b {InterfaceDemo2.exe!CIF2::IF9(void)}     void * 
[3]     0x00000000     void *

 

從上面的虛函數(shù)表,我們可以分析出來(lái),每個(gè)父類都有自己的虛函數(shù)表,子類的虛函數(shù)被放到了第一個(gè)父類的表中。第一個(gè)父類是按照聲明順序來(lái)判斷的。

實(shí)現(xiàn)多態(tài)的多繼承

上面說(shuō)的是沒(méi)有發(fā)生重寫的情況,現(xiàn)在來(lái)說(shuō)說(shuō)發(fā)生重寫的情況;比如,現(xiàn)在有以下情況:

C++ COM編程之接口背后的虛函數(shù)表

在子類中重寫了父類的虛函數(shù),那它的虛函數(shù)表又是什么樣子呢?

虛函數(shù)表CIF1,如下:

 

復(fù)制代碼代碼如下:

[0]     0x012013cf {InterfaceDemo2.exe!CIF3::IF1(void)}     void * 
[1]     0x012012d5 {InterfaceDemo2.exe!CIF1::IF2(void)}     void * 
[2]     0x0120134d {InterfaceDemo2.exe!CIF1::IF3(void)}     void * 
[3]     0x01201456 {InterfaceDemo2.exe!CIF3::IF4(void)}     void * 
[4]     0x012014d8 {InterfaceDemo2.exe!CIF3::IF5(void)}     void * 
[5]     0x00000000     void *

 

虛函數(shù)表CIF2,如下:

 

復(fù)制代碼代碼如下:

[0]     0x012014e2 {InterfaceDemo2.exe![thunk]:CIF3::IF1`adjustor{4}' (void)}     void * 
[1]     0x012014ce {InterfaceDemo2.exe!CIF2::IF2(void)}     void * 
[2]     0x012014d3 {InterfaceDemo2.exe!CIF2::IF3(void)}     void * 
[3]     0x00000000     void *

 

從上面的虛函數(shù)表中,我們可以看到虛函數(shù)表中的CIF1::IF1(void)全都被替換成了CIF3::IF1(void),那么我們就可以以任意的父類指針來(lái)調(diào)用IF1(void),實(shí)際上調(diào)用的是CIF3::IF1(void),這就實(shí)現(xiàn)了所謂的多態(tài)。

總結(jié)

總結(jié)了這么多關(guān)于虛函數(shù)表的內(nèi)容,感覺(jué)很扯,和接口沒(méi)有多大的關(guān)系;但是,這一切都是COM的基礎(chǔ),COM的背后,就是接口,而接口的背后,就是我這里總結(jié)的,說(shuō)白了,完全了解了這里,對(duì)于理解COM的接口是有非常大的用處的。希望我的總結(jié)對(duì)大家有用。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
mm131美女视频| 欧美少妇一区二区三区| www.国产视频| 热re99久久国产精品| 中文字幕激情视频| 国产精品区二区三区日本| 天天天天天天天操| 亚洲成人免费在线视频| 欧美激情麻豆| 亚洲成av人片在线观看香蕉| 三级在线观看视频| 91丨九色丨蝌蚪富婆spa| 亚洲永久免费视频| 日韩欧美国产骚| 国产一区二区伦理| 国产福利电影在线| 久久久亚洲精品视频| 成人免费一区二区三区在线观看| 久久精品成人一区二区三区| 少妇人妻精品一区二区三区| 亚洲av综合色区无码一二三区| 日本久久国产| 国产亚洲精品熟女国产成人| 久久一区二区精品| 日韩一级片免费视频| 国产福利一区二区| 2019男人天堂| 最近中文字幕av免费高清| av免费不卡国产观看| 久久精品视频国产| 天天操天天曰| 中文字幕欧美国内| 国产精品无码天天爽视频| 中文字幕欧美人与畜| 国产精品v日韩精品v在线观看| 亚洲国产视频一区二区| 欧美精品一区免费| 水蜜桃av无码| 欧美一区二区视频免费观看| 亚洲欧美一区二区三区四区五区| 中文人妻熟女乱又乱精品| 一区二区免费看| 黄页在线观看免费| 理论片一区二区在线| 国产三级视频在线播放| 91在线视频成人| 国产综合av在线| 日本少妇bbwbbw精品| 91九色02白丝porn| 理论片大全免费理伦片| k8久久久一区二区三区| 国产精品亚洲а∨天堂免在线| 婷婷久久综合九色国产成人| 六月婷婷激情综合| 国产+人+亚洲| 欧美亚洲日本在线观看| 国产精品视频一二三区| 精品无线一线二线三线| 男人午夜天堂| 男人在线观看视频| 中文字幕黄色网址| 少妇太紧太爽又黄又硬又爽小说| 日韩美脚连裤袜丝袜在线| 可以在线观看的黄色| 欧美精品情趣视频| 在线永久看片免费的视频| 国产九色在线| 亚洲人成电影院在线观看| 国产成人精品一区二区在线| 欧美大成色www永久网站婷| 久久视频在线看| 精品综合久久88少妇激情| 一二三四区视频| 国产精品一区二区三区四区五区| 亚洲国产高清av| 国产一区二区三区影院| yjizz国产| www国产精品视频| 国产精品久久久久影院| www亚洲国产| 成年人视频网站免费| 精品国产一二三区| 日韩va亚洲va欧洲va国产| 伊人免费视频2| 可以直接在线观看的av| 国产区二区三区| 蜜桃视频在线观看成人| 国产午夜精品麻豆| 538国产精品视频一区二区| 久久婷婷国产综合国色天香| 国产午夜福利在线播放| 国产成人精品久久一区二区小说| 日韩美女毛片| 欧美极品少妇xxxxx| 久久久久女教师免费一区| 亚洲国产精品成人无久久精品| 欧美日韩在线视频播放| 精品国产一区av| 国产在线精品一区二区三区》| 高h视频在线观看| 一本大道久久a久久精二百| 91九色国产社区在线观看| 国产一二三在线| 国产白浆在线观看| 97在线免费公开视频| 日韩av成人在线观看| 一级做a爱片久久| 性生交大片免费看女人按摩| 亚洲欧美一区二区精品久久久| 亚洲国产一区二区a毛片| 中文字幕日韩视频| 亚洲成年人影院在线| 国产人成免费视频| 色播色播色播色播色播在线| 国产成人欧美在线观看| 欧美大片网站| 成人av在线网| 久久亚洲精品中文字幕蜜潮电影| 三级av免费观看| 可以在线观看的av网站| 中文字幕日韩精品一区二区| 亚洲爆乳无码专区| 天堂中文在线网| 成年人黄色电影| 中文字幕一区二区三区av| 亚洲婷婷在线视频| 96精品视频在线| 一级黄色录像在线观看| 国产xxx精品视频大全| 欧美亚洲综合在线| 男插女视频网站| 天堂网.www在线资源| 91九色porny视频| 亚洲精品一区二区三区在线观看| 久久久一区二区三区捆绑**| 国产一区二区三区在线看| 国产一区视频在线| 日韩不卡av在线| 国产丝袜美女| 亚洲欧美一区二区视频| 婷婷色在线资源| 亚洲一区免费看| 国产成人在线播放视频| 无码人妻丰满熟妇区毛片| 老太脱裤让老头玩ⅹxxxx| 91成人在线免费观看| 亚洲裸体俱乐部裸体舞表演av| 性感美女一区二区三区| 日本中文字幕免费在线观看| 国产农村妇女毛片精品久久麻豆| 99久久一区三区四区免费| 精品人妻少妇一区二区| 久久久水蜜桃av免费网站| 日本高清不卡一区二区三| 欧美一区二区三区四区五区| av成人亚洲| 精品成人一区二区三区免费视频| 亚洲午夜久久久久久久久电影网| 国产欧美精品在线观看| 欧美综合在线第二页| 一本在线高清不卡dvd| 台湾十八成人网| 无码无套少妇毛多18pxxxx| 99国产精品久久久久久| 国产一区二区三区四区五区在线| 激情六月婷婷综合| 色综合久久一区二区三区| luxu259在线中文字幕| 玖玖玖免费嫩草在线影院一区| 国产精品久久久久久久久久东京| 亚洲天堂岛国片| 伊人久久大香线蕉综合75| 国产精品久久久久久久浪潮网站| 成人在线综合网站| 中文字幕不卡在线观看| 免费网站免费进入在线| 精品国产麻豆| 欧美最猛性xxxxx亚洲精品| 国产精品视频首页| 九九热只有这里有精品| 国产欧美一区二区三区在线看蜜臀| 成人av电影免费| www.黄色小说.com| 无码人妻aⅴ一区二区三区日本| 中文文字幕一区二区三三| 杨幂一区二区国产精品| 国产精品美日韩| 日韩av电影网| 国产成人+综合亚洲+天堂| 92福利视频午夜1000合集在线观看| 日韩黄色a级片| 成人mm视频在线观看| 欧美少妇一区二区| 中文字幕精品无码一区二区| 亚洲欧洲午夜| 91地址最新发布| 亚洲欧美日韩在线| 久久香蕉国产线看观看av| 国内精品免费**视频| 色综合久久久久久中文网| 日本特级黄色片| 亚洲精品中文字幕在线播放| 懂色中文一区二区三区在线视频| 亚洲国产一区二区三区网站| 亚洲国产二区| 欧美一区二粉嫩精品国产一线天| 91精品久久久久久久久中文字幕| 欧美xingq一区二区| 中文字幕在线字幕中文| 亚洲欧美日韩另类精品一区二区三区| 高清毛片aaaaaaaaa片| 久久综合综合久久| 国产精品久久久久久久久男| www在线免费观看| 久久国产综合视频| 在线黄色.com| 日韩精品免费视频| 国产网红主播福利一区二区| 久久av偷拍| 奇米综合一区二区三区精品视频| 不卡在线视频| 国产内射老熟女aaaa∵| 亚洲欧美伊人| 一区二区三区精品在线| 久久久久久久久久久久久夜| 黑人巨大精品欧美黑白配亚洲| 欧美片网站免费| www.中文字幕久久久| 日批视频在线免费看| 欧美日韩一区二区在线观看视频| 在线观看av网站永久| 网站免费在线观看| 国产亚洲精品精品国产亚洲综合| 国产香蕉精品视频一区二区三区| 凹凸日日摸日日碰夜夜| 在线成人一区二区| 国产黄色录像视频| 成人性生交大片免费看中文| 久久精品黄色| 亚洲最新视频在线观看| 亚洲免费福利一区| 精品无码久久久久成人漫画| 日韩午夜av在线| 精品福利网址导航| 五月天最新网址| 国产精品美女高潮无套| 韩国中文字幕av| 亚洲毛片在线观看.| 国产一级一区二区| 国产黄色美女视频| 中文字幕一区二区三区av| 少妇bbbb搡bbbb| 欧美v亚洲v综合v国产v仙踪林| 国产黄色片免费看| 亚洲成年人在线| 3d动漫精品啪啪一区二区下载| http;//www.99re视频| av电影在线观看完整版一区二区| 国产日韩精品一区观看| 亚洲第一视频区| 欧美精品成人一区二区三区四区| 久久永久免费| 亚洲综合清纯丝袜自拍| 久久综合久久综合亚洲| 日韩大陆毛片av| 国产精品久久一级| 漂亮人妻被黑人久久精品| 久久久久久亚洲精品美女| 中文字幕国内自拍| 人妻91麻豆一区二区三区| 伊人中文字幕在线| 日韩—二三区免费观看av| 电影天堂av在线| 伊人色综合久久天天五月婷| 114国产精品久久免费观看| 国产综合久久久久影院| 日韩大片免费观看| 国产一区再线| 欧美一区二区视频观看视频| 亚洲欧洲成视频免费观看| 亚洲天堂2020| 国产精品黑丝在线播放| 中文在线不卡| 日韩成人av网| 亚洲va久久久噜噜噜久久天堂| 亚洲国产精一区二区三区性色| 欧美黑人性猛交| 中文字幕av久久| 日韩在线观看视频一区| 久久久国产精品午夜一区ai换脸| 亚洲一区二区四区| 最近中文字幕在线观看| 色香蕉成人二区免费| www激情五月| 国产视频在线视频| 97人人模人人爽人人喊中文字| 91精品国产免费久久久久久| a天堂视频在线观看| 91porn在线| 成人欧美精品一区二区| 日韩国产在线不卡视频| 国产极品一区| 主播大秀视频在线观看一区二区| 九九热精品视频在线观看| 99久久亚洲精品蜜臀| 成人av免费播放| 影音先锋国产在线| 国产蜜臀av在线播放| 91桃色在线| 日韩美脚连裤袜丝袜在线| 亚洲嫩模很污视频| 日韩精品免费综合视频在线播放| 欧美一区二区三区在线观看免费| 国内在线免费视频| 国产日本一区二区三区| 黄网站色视频免费观看| 亚洲在线观看| 国产精品成人aaaaa网站| 香蕉视频免费网站| 醉酒壮男gay强迫野外xx| 91成人网在线观看| 91成人免费在线| 亚洲日本中文字幕| 成人综合专区| 国产亚洲精久久久久久| 久久久久久综合网| 国产三级电影| 久久久久久久9999|