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

COM 本質論筆記 第一章 com 是一個更好的c++

Posted on 2011-08-21 16:19 rikisand 閱讀(2515) 評論(2)  編輯 收藏 引用 所屬分類: C/C++

Basic Sample Senario :

Client 需要一種組件提供一種 FastString類, 此類具有 int length() 方法

解決方案:

靜態鏈接 : 組件廠商將源代碼交給 client ,客戶將組件代碼與client 代碼編譯連接運行。 如果組件代碼需要fix bug or update ,則client 端代碼需要重新編譯連接。 而且client軟件的不同實例使用各自的組件內存對象。

動態鏈接 : 組件廠商使用DLL形式發放組件,此時不同的client實例可以共享組件在內存中的代碼段。

DLL的問題:1.導出名稱的問題 : 不同的compiler可以使用不同的mangle name 用來區分 c++的函數,那么使用不同的compiler的client和組件無法鏈接 (可以使用extern “C”解決全局函數名的問題,使用 .DEF文件解決導出成員函數的問題)

                   2.升級的問題 :如果組件最初定義為

class FastString
{
    char* m_psz;
public:
    FastString(const char* psz){strcpy(m_psz, psz);}
};

                                          而后廠商更改了組件的實現

class FastString
{
int newmember;
char* psz;
public:

FastString(const char* psz){strcpy(m_psz, psz);}

}

原來FastString對象大小為4字節,現在變為8字節,但是client端按照4字節分配對象, dll卻要向后面的4個字節存入一個指針,行為不可預料!

解決這一問題的一種方法便是每次發布便更改dll的名字,即1.0, 2.0, x.0 等等。但這樣比較弱啊!!

這種問題根本原因是啥呢?

class 的關鍵在于封裝了其中的實現細節,即用戶知道類提供了哪些服務( public方法)就行了,不需要管類的內部到底使用了哪些成員變量。這樣一來,只要接口沒變(類提供功能),user就可以安心的使用任意版本的實現了。C++怎么不行呢?C++告訴用戶接口的同時,也告訴了用戶類的實現(對象布局)。比如類對象有多大啊,每個成員的偏移啊(具體可以看Inside c++ object model)。知道了這些,客戶端使用接口的代碼就和DLL中的具體實現緊密的耦合起來了,杯具 啊~

咋辦呢? 只要不讓client直接創建FastString就行了,這樣client的代碼就不會受到FastString實現變化的影響了。給FastString加一個Wrapper類,內部嵌套一個FastString,所有對FastString的調用都foward給內部的FastString member, 創建FastString 的任務在dll方面完成,client只知道Wrapper大小為4個字節--指向FastString的指針。這樣問題解決了,但是太麻煩了,所有的接口都要包一層!! 而且多了一層調用!

還有啥辦法么? 為了保證c++接口類實現二進制級別的兼容只能使用編譯器無關的特性:1.假設復合類型表現形式相同(struct) 2. 傳參順序相同,可以使用指示符指定3.虛函數調用機制相同,即基于 vtbl 和 vptr. 基于這些假設,我們創建的c++接口類所有函數設置為虛函數,那么不同compiler將為客戶端方法調用產生相同的機器代碼。定義了接口,便規定了所有繼承于他的類的內存結構一定與它兼容。但此時不能告訴用戶類的定義,否則重回上面的老路上了。怎么辦,只有接口客戶無法創建類的定義,只有export一個創建類對象的函數客戶了。  同上面的wrapper一樣,創建類的操作僅僅在dll內部調用,這意味著實際建造類對象大小和布局的代碼與編譯實現類的方法的代碼使用同樣的編譯器創建 (即ctor和call ctor的代碼由同一編譯器同時編譯)。由于虛析構函數在vtbl的位置與compiler相關,所以不能把它設置為虛函數,只有顯示增加一個Delete函數完成析構工作。

OK,當前我們得到的DLL中只有創建類對象的函數需要用extern “C”export 給客戶,其他的接口中的虛函數是通過虛表訪問的,無需靠符號名字鏈接。

進一步的,如果我們要給接口增加一個功能呢? 如果直接在現有接口中方法聲明后加入新的方法,那么此方法會出現在vtbl的最后一欄,舊的client不會調用新方法,但是如果新的client訪問老的對象呢? 不幸的事情發生了! 這樣做的問題在于,修改公開的接口就打破了對象的封裝性。

那么增加接口功能只能通過設計一個接口繼承另一個接口,或者讓類繼承多個接口來實現了。客戶可以在運行時通過RTTI來詢問對象,支持這個功能不,親?然而 ,RTTI也是一個compiler相關的東東,好吧,我們讓每個類自己實現RTTI,也就是實現一個dynamic_cast 方法, 用來將自己cast成為自己實現的接口,如果不支持則返回 0 。

例如:

void* CFastString::Dynamic_Cast(const char* pszTypename)
{
void * pRev;
if(strcmp(pszTypename, "IFastString") == 0)
{
pRev = static_cast<IFastString*>(this);
}
else if(strcmp(pszTypename , "IOut") == 0)
{
pRev = static_cast<IOut*>(this);
}
else if(strcmp(pszTypename , "IExtent") == 0)
{
pRev = static_cast<IFastString*>(this);
}
else
{
return 0;
}

return pRev;
}

注意cast到IExtent的時候用了IFastString,因為IFastString 和 IOut都是從IExtent繼承的,寫IExtent的話不知道用哪個,用虛擬繼承可以使CFastString對象只有一份IExtent,為啥不用呢? 你懂得。。。跟前面答案一樣,編譯器相關。

最后一個問題是delete的問題,用戶需要記得為每一個對象調用一次delete方法,而指針cast來cast去,想記得對象被delete沒有很難啊! 怎么辦? 用引用計數吧,把每個指針當做具有生命周期的實體,創建時候計數++,銷毀時候--,等到0的時候就delete對象。

大功告成,通過vptr和vtbl的二進制防火墻,我們做到了可重用的二進制組件,組件變化客戶無需重新編譯 。

Feedback

# re: COM 本質論筆記 第一章 com 是一個更好的c++  回復  更多評論   

2011-08-23 23:51 by 陳梓瀚(vczh)
更新的時候連exe一起換掉就好了,現在網速那么快

# re: COM 本質論筆記 第一章 com 是一個更好的c++  回復  更多評論   

2011-09-05 11:42 by 戰痘小天使
up,期待第二篇
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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| 国产精品扒开腿做爽爽爽软件| 欧美激情视频一区二区三区在线播放 | 亚洲黄色三级| 日韩午夜电影av| 中文有码久久| 久久精品99久久香蕉国产色戒| 久久网站热最新地址| 亚洲国产精品成人va在线观看| 亚洲黄页视频免费观看| 在线亚洲一区观看| 久久综合给合| 国产精品国产三级国产aⅴ9色| 国产日韩欧美黄色| 亚洲美女中出| 久久精品国产一区二区三| 亚洲国产精品一区二区www| 亚洲视频免费看| 老牛国产精品一区的观看方式| 欧美日本视频在线| 狠狠色综合色区| 亚洲欧美精品伊人久久| 蜜臀va亚洲va欧美va天堂| 在线亚洲精品| 欧美精品一区二区视频 | 日韩天天综合| 久久精品国产精品| 亚洲精品美女在线观看播放| 久久国产精品一区二区三区四区| 欧美日韩国产a| 91久久综合| 久久久夜夜夜| 亚洲综合电影一区二区三区| 欧美另类一区二区三区| 在线精品视频在线观看高清 | 国外成人网址| 欧美亚洲视频一区二区| 亚洲国产欧美另类丝袜| 亚洲欧美资源在线| 亚洲福利国产精品| 久久精品一区二区三区中文字幕 | 欧美激情在线观看| 久久精品99国产精品酒店日本| 国产精品二区在线| 亚洲亚洲精品三区日韩精品在线视频| 欧美福利精品| 久久综合色婷婷| 激情综合网激情| 久久激情五月丁香伊人| 亚洲免费视频观看| 国产日产欧产精品推荐色| 亚洲女同在线| 亚洲——在线| 国产欧美一区二区三区久久| 欧美在线网站| 欧美一区二区三区在线播放| 国产日韩欧美三级| 久久天天躁狠狠躁夜夜爽蜜月| 久久精彩免费视频| 亚洲国产精品一区制服丝袜| 欧美激情第六页| 欧美a一区二区| 一本久久综合亚洲鲁鲁五月天| 日韩亚洲欧美高清| 国产伦精品一区二区三区免费| 午夜精品一区二区三区在线| 亚洲一品av免费观看| 国产亚洲欧美一区在线观看| 久久久欧美一区二区| 久久综合狠狠| 一本色道久久综合亚洲精品婷婷| 99热免费精品在线观看| 国产精一区二区三区| 久久久成人精品| 麻豆成人在线播放| 亚洲一区二区免费| 欧美一区二区免费| 亚洲国产精品嫩草影院| 日韩一级不卡| 国产综合色在线| 91久久精品一区| 国产伦精品一区二区三区高清| 久久色中文字幕| 欧美久久一区| 久久久久欧美精品| 欧美另类一区| 久久久噜噜噜久久人人看| 女人香蕉久久**毛片精品| 亚洲在线黄色| 久久久久www| 亚洲一区二区免费视频| 久久久噜噜噜久久| 亚洲欧美在线播放| 免费在线观看精品| 欧美一区三区三区高中清蜜桃 | 免费在线亚洲欧美| 国产日产欧美精品| 美日韩在线观看| 欧美日韩无遮挡| 麻豆成人综合网| 国产精品扒开腿做爽爽爽视频| 小处雏高清一区二区三区| 免费成人激情视频| 久久国产日韩| 国产精品二区在线| 亚洲激情第一区| 海角社区69精品视频| 在线亚洲一区| 一区二区欧美精品| 蜜臀av性久久久久蜜臀aⅴ四虎 | 欧美成人一二三| 久久精品视频va| 国产精品视频男人的天堂| 亚洲人成啪啪网站| 亚洲国产精品综合| 久久久久国产一区二区三区| 欧美亚洲三区| 国产精品一二三四| 国产精品99久久久久久久女警| 亚洲精品1区2区| 久久亚洲春色中文字幕| 久久婷婷国产麻豆91天堂| 国产乱码精品一区二区三区不卡| 日韩一级精品| 亚洲一区二区三区免费视频 | 国产精品xxxxx| 亚洲欧洲日产国码二区| 亚洲人体影院| 欧美激情第1页| 亚洲美女av电影| 亚洲无毛电影| 欧美视频一区在线| 一本色道久久综合亚洲精品按摩| 一区二区三区欧美激情| 欧美激情在线播放| 亚洲黄色成人久久久| 99成人免费视频| 欧美日韩免费高清| 亚洲香蕉网站| 久久久久成人精品免费播放动漫| 国产一区二区三区精品欧美日韩一区二区三区 | 欧美日韩综合精品| 9i看片成人免费高清| 亚洲视频在线观看网站| 欧美性猛交xxxx免费看久久久 | 亚洲一区二区三区免费在线观看| 亚洲你懂的在线视频| 国产日产高清欧美一区二区三区| 欧美亚洲视频一区二区| 麻豆成人在线观看| 欧美日韩精品伦理作品在线免费观看| 亚洲精品在线三区| 午夜欧美大片免费观看| 精品动漫av| 欧美日韩一区在线视频| 亚洲一区二区三区在线播放| 久久久久免费视频| 亚洲毛片在线| 国产女主播一区二区三区| 久久视频在线看| 一区二区三区视频在线看| 久久久久久一区二区| 亚洲精品综合| 国产日韩欧美高清| 欧美激情久久久久久| 亚洲一区二区四区| 亚洲电影在线| 久久国产精品高清| 99精品视频免费全部在线| 国产日韩欧美不卡在线| 嫩模写真一区二区三区三州| 亚洲一区二区三区免费在线观看 | 欧美少妇一区| 久久久精品网| 在线亚洲国产精品网站| 欧美成人亚洲成人日韩成人| 午夜亚洲视频| 日韩视频精品在线| 精品999成人| 国产精品国产三级国产普通话蜜臀 | 亚洲无线一线二线三线区别av| 国产一区二区丝袜高跟鞋图片 | 国产精品高潮久久| 久久久在线视频| 亚洲一区二区三区激情| 亚洲激情啪啪| 欧美jizzhd精品欧美巨大免费| 欧美一区二区三区在线视频 | 欧美国产日韩视频| 久久成人免费日本黄色| 亚洲宅男天堂在线观看无病毒| 亚洲国产精品一区二区第一页| 久久免费国产| 久久精品国产欧美亚洲人人爽| 亚洲欧美日韩成人| 亚洲午夜电影网|