锘??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲精品中文字幕在线,国产精品国产三级国产aⅴ浪潮,在线观看一区二区精品视频http://www.shnenglu.com/SpringSnow/category/8521.html闆寲浜嗭紝鑺卞紑浜嗭紝鏄ュぉ鏉ヤ簡zh-cnWed, 29 Jul 2009 03:52:41 GMTWed, 29 Jul 2009 03:52:41 GMT60杞細浣嶈繍綆楃鐨勪竴浜涚畝鍗曞簲鐢?http://www.shnenglu.com/SpringSnow/articles/91499.htmlSandySandyTue, 28 Jul 2009 08:21:00 GMThttp://www.shnenglu.com/SpringSnow/articles/91499.htmlhttp://www.shnenglu.com/SpringSnow/comments/91499.htmlhttp://www.shnenglu.com/SpringSnow/articles/91499.html#Feedback0http://www.shnenglu.com/SpringSnow/comments/commentRss/91499.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/91499.html杞繃鏉ヤ簡銆?br>
鎽樿嚜錛?a href="http://www.shnenglu.com/pengkuny/archive/2007/04/21/22551.html">http://www.shnenglu.com/pengkuny/archive/2007/04/21/22551.html

浣嶈繍綆楃鏈夛細&(鎸変綅涓?銆亅(鎸変綅鎴?銆乛(鎸変綅寮傛垨)銆亊 (鎸変綅鍙栧弽)銆?
浼樺厛綰т粠楂樺埌浣庯紝渚濇涓簙銆?amp;銆乛銆亅錛?

浣嶈繍綆楃鐨勪竴浜涚畝鍗曞簲鐢?
鎸変綅涓庤繍綆楁湁涓ょ鍏稿瀷鐢ㄦ硶錛屼竴鏄彇涓涓綅涓蹭俊鎭殑鏌愬嚑浣嶏紝濡備互涓嬩唬鐮佹埅鍙杧鐨勬渶浣?浣嶏細x & 0177銆備簩鏄鏌愬彉閲忎繚鐣欐煇鍑犱綅錛屽叾浣欎綅緗?錛屽浠ヤ笅浠g爜璁﹛鍙繚鐣欐渶浣?浣嶏細x = x & 077銆?/p>

鎸変綅鎴栬繍綆楃殑鍏稿瀷鐢ㄦ硶鏄皢涓涓綅涓蹭俊鎭殑鏌愬嚑浣嶇疆鎴?銆傚灝嗚鑾峰緱鏈鍙?涓?錛屽叾浠栦綅涓庡彉閲廽鐨勫叾浠栦綅鐩稿悓錛屽彲鐢ㄩ昏緫鎴栬繍綆?17|j

鎸変綅寮傛垨榪愮畻鐨勫吀鍨嬬敤娉曟槸姹備竴涓綅涓蹭俊鎭殑鏌愬嚑浣嶄俊鎭殑鍙嶃傚嬈叉眰鏁村瀷鍙橀噺j鐨勬渶鍙?浣嶄俊鎭殑鍙嶏紝鐢ㄩ昏緫寮傛垨榪愮畻017^j錛屽氨鑳芥眰寰梛鏈鍙?浣嶇殑淇℃伅鐨勫弽,鍗沖師鏉ヤ負1鐨勪綅錛岀粨鏋滄槸0,鍘熸潵涓?鐨勪綅錛岀粨鏋滄槸1銆?浜ゆ崲涓や釜鍊鹼紝涓嶇敤涓存椂鍙橀噺,鍋囧a=3,b=4銆傛兂灝哸鍜宐鐨勫間簰鎹紝鍙互鐢ㄤ互涓嬭祴鍊艱鍙ュ疄鐜幫細
a=a^b;  b=b^a;     a=a^b;

鍙栧弽榪愮畻甯哥敤鏉ョ敓鎴愪笌緋葷粺瀹炵幇鏃犲叧鐨勫父鏁般傚瑕佸皢鍙橀噺x鏈浣?浣嶇疆鎴?錛屽叾浣欎綅涓嶅彉錛屽彲鐢ㄤ唬鐮亁 = x & ~077瀹炵幇銆備互涓婁唬鐮佷笌鏁存暟x鐢?涓瓧鑺傝繕鏄敤4涓瓧鑺傚疄鐜版棤鍏熾?
褰撲袱涓暱搴︿笉鍚岀殑鏁版嵁榪涜浣嶈繍綆楁椂(渚嬪long鍨嬫暟鎹笌int鍨嬫暟鎹?錛屽皢涓や釜榪愮畻鍒嗛噺鐨勫彸绔榻愯繘琛屼綅榪愮畻銆傚鏋滅煭鐨勬暟涓烘鏁幫紝楂樹綅鐢?琛ユ弧錛涘鏋滅煭鐨勬暟涓鴻礋鏁幫紝楂樹綅鐢?琛ユ弧銆傚鏋滅煭鐨勪負鏃犵鍙鋒暣鏁幫紝鍒欓珮浣嶆繪槸鐢?琛ユ弧銆?/p>

浣嶈繍綆楃敤鏉ュ浣嶄覆淇℃伅榪涜榪愮畻錛屽緱鍒頒綅涓蹭俊鎭粨鏋溿傚浠ヤ笅浠g爜鑳藉彇涓嬫暣鍨嬪彉閲弅鐨勪綅涓蹭俊鎭殑鏈鍙寵竟涓?鐨勪俊鎭綅錛?(k-1)^k) & k銆?

瀵逛簬甯︾鍙風殑鏁版嵁錛屽鏋滅Щ浣嶅墠絎﹀彿浣嶄負0(姝f暟)錛屽垯宸︾涔熸槸鐢?琛ュ厖錛涘鏋滅Щ浣嶅墠絎﹀彿浣嶄負1(璐熸暟)錛屽垯宸︾鐢?鎴栫敤1琛ュ厖錛屽彇鍐充簬璁$畻鏈虹郴緇熴傚浜庤礋鏁板彸縐伙紝縐扮敤0 琛ュ厖鐨勭郴緇熶負“閫昏緫鍙崇Щ”錛岀敤1琛ュ厖鐨勭郴緇熶負“綆楁湳鍙崇Щ”銆備互涓嬩唬鐮佽兘璇存槑璇昏呬笂鏈虹殑緋葷粺鎵閲囩敤鐨勫彸縐繪柟娉曪細
     printf("%d\n\n\n", -2>>4);
鑻ヨ緭鍑虹粨鏋滀負-1錛屾槸閲囩敤綆楁湳鍙崇Щ錛涜緭鍑虹粨鏋滀負涓涓ぇ鏁存暟錛屽垯涓洪昏緫鍙崇Щ銆?/p>

縐諱綅榪愮畻涓庝綅榪愮畻緇撳悎鑳藉疄鐜拌澶氫笌浣嶄覆榪愮畻鏈夊叧鐨勫鏉傝綆椼傝鍙橀噺鐨勪綅鑷彸鑷沖乏欏哄簭緙栧彿錛岃嚜0浣嶈嚦15浣嶏紝鏈夊叧鎸囧畾浣嶇殑琛ㄨ揪寮忔槸涓嶈秴榪?5鐨勬鏁存暟銆備互涓嬪悇浠g爜鍒嗗埆鏈夊畠浠彸杈規敞閲婃墍紺虹殑鎰忎箟錛?br>   (1) 鍒ゆ柇int鍨嬪彉閲廰鏄鏁拌繕鏄伓鏁?灝ゅ叾鏄澶ф暟鐨勫垽鏂?br>        a&1 == 0 鍋舵暟
        a&1 == 1 濂囨暟
    (2) 鍙杋nt鍨嬪彉閲廰鐨勭k浣?(k=0,1,2……sizeof(int))
 a>>k&1
    (3) 灝唅nt鍨嬪彉閲廰鐨勭k浣嶆竻0
 a=a&~(1<<k)
    (4) 灝唅nt鍨嬪彉閲廰鐨勭k浣嶇疆1
 a=a|(1<<k)
    (5) int鍨嬪彉閲忓驚鐜乏縐籯嬈?br> a=a<<k|a>>16-k   (璁緎izeof(int)=16)
    (6) int鍨嬪彉閲廰寰幆鍙崇Щk嬈?br> a=a>>k|a<<16-k   (璁緎izeof(int)=16)
    (7) 瀹炵幇鏈浣巒浣嶄負1錛屽叾浣欎綅涓?鐨勪綅涓蹭俊鎭?
 ~錛垀0 << n錛?
    (8)鎴彇鍙橀噺x鑷猵浣嶅紑濮嬬殑鍙寵竟n浣嶇殑淇℃伅:
 (x >> (1+p-n)) & ~(~0 << n) 
    (9)鎴彇old鍙橀噺絎瑀ow浣嶏紝騫跺皢璇ヤ綅淇℃伅瑁呴厤鍒板彉閲弉ew鐨勭15-k浣?br> new |= ((old >> row) & 1) << (15 – k)
    (10)璁緎涓嶇瓑浜庡叏0錛屼唬鐮佸鎵炬渶鍙寵竟涓?鐨勪綅鐨勫簭鍙穓:
 for(j = 0; ((1 << j) & s) == 0; j++) ;


鏈変簺鐢ㄦ硶榪樻湭鑰冭瘉

Sandy 2009-07-28 16:21 鍙戣〃璇勮
]]>
杞? C++ 铏氬嚱鏁拌〃瑙f瀽http://www.shnenglu.com/SpringSnow/articles/89181.htmlSandySandyFri, 03 Jul 2009 09:32:00 GMThttp://www.shnenglu.com/SpringSnow/articles/89181.htmlhttp://www.shnenglu.com/SpringSnow/comments/89181.htmlhttp://www.shnenglu.com/SpringSnow/articles/89181.html#Feedback0http://www.shnenglu.com/SpringSnow/comments/commentRss/89181.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/89181.htmlC++ 铏氬嚱鏁拌〃瑙f瀽

 

闄堢殦

http://blog.csdn.net/haoel

 

 

鍓嶈█
 

C++涓殑铏氬嚱鏁扮殑浣滅敤涓昏鏄疄鐜頒簡澶氭佺殑鏈哄埗銆傚叧浜庡鎬侊紝綆鑰岃█涔嬪氨鏄敤鐖剁被鍨嬪埆鐨勬寚閽堟寚鍚戝叾瀛愮被鐨勫疄渚嬶紝鐒跺悗閫氳繃鐖剁被鐨勬寚閽堣皟鐢ㄥ疄闄呭瓙綾葷殑鎴愬憳鍑芥暟銆傝繖縐嶆妧鏈彲浠ヨ鐖剁被鐨勬寚閽堟湁“澶氱褰㈡?#8221;錛岃繖鏄竴縐嶆硾鍨嬫妧鏈傛墍璋撴硾鍨嬫妧鏈紝璇寸櫧浜嗗氨鏄瘯鍥句嬌鐢ㄤ笉鍙樼殑浠g爜鏉ュ疄鐜板彲鍙樼殑綆楁硶銆傛瘮濡傦細妯℃澘鎶鏈紝RTTI鎶鏈紝铏氬嚱鏁版妧鏈紝瑕佷箞鏄瘯鍥懼仛鍒板湪緙栬瘧鏃跺喅璁紝瑕佷箞璇曞浘鍋氬埌榪愯鏃跺喅璁?/p>

 

 

鍏充簬铏氬嚱鏁扮殑浣跨敤鏂規硶錛屾垜鍦ㄨ繖閲屼笉鍋氳繃澶氱殑闃愯堪銆傚ぇ瀹跺彲浠ョ湅鐪嬬浉鍏崇殑C++鐨勪功綾嶃傚湪榪欑瘒鏂囩珷涓紝鎴戝彧鎯充粠铏氬嚱鏁扮殑瀹炵幇鏈哄埗涓婇潰涓哄ぇ瀹?涓涓竻鏅扮殑鍓栨瀽銆?/p>

 

褰撶劧錛岀浉鍚岀殑鏂囩珷鍦ㄧ綉涓婁篃鍑虹幇榪囦竴浜涗簡錛屼絾鎴戞繪劅瑙夎繖浜涙枃绔犱笉鏄緢瀹規槗闃呰錛屽ぇ孌靛ぇ孌電殑浠g爜錛屾病鏈夊浘鐗囷紝娌℃湁璇︾粏鐨勮鏄庯紝娌℃湁姣旇緝錛屾病鏈変婦涓鍙嶄笁銆備笉鍒╀簬瀛︿範鍜岄槄璇伙紝鎵浠ヨ繖鏄垜鎯沖啓涓嬭繖綃囨枃绔犵殑鍘熷洜銆備篃甯屾湜澶у澶氱粰鎴戞彁鎰忚銆?/p>

 

璦褰掓浼狅紝璁╂垜浠竴璧瘋繘鍏ヨ櫄鍑芥暟鐨勪笘鐣屻?/p>

 

 

铏氬嚱鏁拌〃
 

瀵笴++ 浜嗚В鐨勪漢閮藉簲璇ョ煡閬撹櫄鍑芥暟錛圴irtual Function錛夋槸閫氳繃涓寮犺櫄鍑芥暟琛紙Virtual Table錛夋潵瀹炵幇鐨勩傜畝縐頒負V-Table銆傚湪榪欎釜琛ㄤ腑錛屼富鏄涓涓被鐨勮櫄鍑芥暟鐨勫湴鍧琛紝榪欏紶琛ㄨВ鍐充簡緇ф壙銆佽鐩栫殑闂錛屼繚璇佸叾瀹圭湡瀹炲弽搴斿疄闄呯殑鍑芥暟銆傝繖鏍鳳紝鍦ㄦ湁铏氬嚱鏁扮殑綾葷殑瀹炰緥涓繖涓〃琚垎閰嶅湪浜嗚繖涓疄渚嬬殑鍐呭瓨涓紝鎵浠ワ紝褰撴垜浠敤鐖剁被鐨勬寚閽堟潵鎿嶄綔涓涓瓙綾葷殑鏃跺欙紝榪欏紶铏氬嚱鏁拌〃灝辨樉寰楃敱涓洪噸瑕佷簡錛屽畠灝卞儚涓涓湴鍥句竴鏍鳳紝鎸囨槑浜嗗疄闄呮墍搴旇璋冪敤鐨勫嚱鏁般?/p>

 

榪欓噷鎴戜滑鐫閲嶇湅涓涓嬭繖寮犺櫄鍑芥暟琛ㄣ侰++鐨勭紪璇戝櫒搴旇鏄繚璇佽櫄鍑芥暟琛ㄧ殑鎸囬拡瀛樺湪浜庡璞″疄渚嬩腑鏈鍓嶉潰鐨勪綅緗紙榪欐槸涓轟簡淇濊瘉鍙栧埌铏氬嚱鏁拌〃鐨勬湁鏈楂樼殑鎬ц兘鈥斺斿鏋滄湁澶氬眰緇ф壙鎴栨槸澶氶噸緇ф壙鐨勬儏鍐典笅錛夈?榪欐剰鍛崇潃鎴戜滑閫氳繃瀵硅薄瀹炰緥鐨勫湴鍧寰楀埌榪欏紶铏氬嚱鏁拌〃錛岀劧鍚庡氨鍙互閬嶅巻鍏朵腑鍑芥暟鎸囬拡錛屽茍璋冪敤鐩稿簲鐨勫嚱鏁般?/p>

 

鍚垜鎵簡閭d箞澶氾紝鎴戝彲浠ユ劅瑙夊嚭鏉ヤ綘鐜板湪鍙兘姣斾互鍓嶆洿鍔犳檿澶磋漿鍚戜簡銆?娌″叧緋伙紝涓嬮潰灝辨槸瀹為檯鐨勪緥瀛愶紝鐩鎬俊鑱槑鐨勪綘涓鐪嬪氨鏄庣櫧浜嗐?/p>

 

鍋囪鎴戜滑鏈夎繖鏍風殑涓涓被錛?/p>

 

class Base {

     public:

            virtual void f() { cout << "Base::f" << endl; }

            virtual void g() { cout << "Base::g" << endl; }

            virtual void h() { cout << "Base::h" << endl; }

 

};

 

鎸夌収涓婇潰鐨勮娉曪紝鎴戜滑鍙互閫氳繃Base鐨勫疄渚嬫潵寰楀埌铏氬嚱鏁拌〃銆?涓嬮潰鏄疄闄呬緥紼嬶細

 

          typedef void(*Fun)(void);

 

            Base b;

 

            Fun pFun = NULL;

 

            cout << "铏氬嚱鏁拌〃鍦板潃錛? << (int*)(&b) << endl;

            cout << "铏氬嚱鏁拌〃 鈥?絎竴涓嚱鏁板湴鍧錛? << (int*)*(int*)(&b) << endl;

 

            // Invoke the first virtual function 

            pFun = (Fun)*((int*)*(int*)(&b));

            pFun();

 

瀹為檯榪愯緇忔灉濡備笅錛?Windows XP+VS2003,  Linux 2.6.22 + GCC 4.1.3)

 

铏氬嚱鏁拌〃鍦板潃錛?012FED4

铏氬嚱鏁拌〃 鈥?絎竴涓嚱鏁板湴鍧錛?044F148

Base::f

 

 

閫氳繃榪欎釜紺轟緥錛屾垜浠彲浠ョ湅鍒幫紝鎴戜滑鍙互閫氳繃寮鴻鎶?amp;b杞垚int *錛屽彇寰楄櫄鍑芥暟琛ㄧ殑鍦板潃錛岀劧鍚庯紝鍐嶆鍙栧潃灝卞彲浠ュ緱鍒扮涓涓櫄鍑芥暟鐨勫湴鍧浜嗭紝涔熷氨鏄疊ase::f()錛岃繖鍦ㄤ笂闈㈢殑紼嬪簭涓緱鍒頒簡楠岃瘉錛堟妸int* 寮哄埗杞垚浜嗗嚱鏁版寚閽堬級銆傞氳繃榪欎釜紺轟緥錛屾垜浠氨鍙互鐭ラ亾濡傛灉瑕佽皟鐢˙ase::g()鍜孊ase::h()錛屽叾浠g爜濡備笅錛?/p>

 

            (Fun)*((int*)*(int*)(&b)+0);  // Base::f()

            (Fun)*((int*)*(int*)(&b)+1);  // Base::g()

            (Fun)*((int*)*(int*)(&b)+2);  // Base::h()

 

榪欎釜鏃跺欎綘搴旇鎳備簡鍚с備粈涔堬紵榪樻槸鏈夌偣鏅曘備篃鏄紝榪欐牱鐨勪唬鐮佺湅鐫澶貢浜嗐傛病闂錛岃鎴戠敾涓浘瑙i噴涓涓嬨傚涓嬫墍紺猴細

 

 


娉ㄦ剰錛氬湪涓婇潰榪欎釜鍥句腑錛屾垜鍦ㄨ櫄鍑芥暟琛ㄧ殑鏈鍚庡鍔犱簡涓涓粨鐐癸紝榪欐槸铏氬嚱鏁拌〃鐨勭粨鏉熺粨鐐癸紝灝卞儚瀛楃涓茬殑緇撴潫絎?#8220;\0”涓鏍鳳紝鍏舵爣蹇椾簡铏氬嚱鏁拌〃鐨勭粨鏉熴傝繖涓粨鏉熸爣蹇楃殑鍊煎湪涓嶅悓鐨勭紪璇戝櫒涓嬫槸涓嶅悓鐨勩傚湪WinXP+VS2003涓嬶紝榪欎釜鍊兼槸NULL銆傝屽湪Ubuntu 7.10 + Linux 2.6.22 + GCC 4.1.3涓嬶紝榪欎釜鍊兼槸濡傛灉1錛岃〃紺鴻繕鏈変笅涓涓櫄鍑芥暟琛紝濡傛灉鍊兼槸0錛岃〃紺烘槸鏈鍚庝竴涓櫄鍑芥暟琛ㄣ?/p>

 

 

涓嬮潰錛屾垜灝嗗垎鍒鏄?#8220;鏃犺鐩?#8221;鍜?#8220;鏈夎鐩?#8221;鏃剁殑铏氬嚱鏁拌〃鐨勬牱瀛愩傛病鏈夎鐩栫埗綾葷殑铏氬嚱鏁版槸姣棤鎰忎箟鐨勩傛垜涔嬫墍浠ヨ璁茶堪娌℃湁瑕嗙洊鐨勬儏鍐碉紝涓昏鐩殑鏄負浜嗙粰涓涓姣斻傚湪姣旇緝涔嬩笅錛屾垜浠彲浠ユ洿鍔犳竻妤氬湴鐭ラ亾鍏跺唴閮ㄧ殑鍏蜂綋瀹炵幇銆?/p>

 

涓鑸戶鎵匡紙鏃犺櫄鍑芥暟瑕嗙洊錛?br> 

涓嬮潰錛屽啀璁╂垜浠潵鐪嬬湅緇ф壙鏃剁殑铏氬嚱鏁拌〃鏄粈涔堟牱鐨勩傚亣璁炬湁濡備笅鎵紺虹殑涓涓戶鎵垮叧緋伙細

 

 


 

璇鋒敞鎰忥紝鍦ㄨ繖涓戶鎵垮叧緋諱腑錛屽瓙綾繪病鏈夐噸杞戒換浣曠埗綾葷殑鍑芥暟銆傞偅涔堬紝鍦ㄦ淳鐢熺被鐨勫疄渚嬩腑錛屽叾铏氬嚱鏁拌〃濡備笅鎵紺猴細

 

 

瀵逛簬瀹炰緥錛欴erive d; 鐨勮櫄鍑芥暟琛ㄥ涓嬶細

 

 

 

鎴戜滑鍙互鐪嬪埌涓嬮潰鍑犵偣錛?/p>

1錛夎櫄鍑芥暟鎸夌収鍏跺0鏄庨『搴忔斁浜庤〃涓?/p>

2錛夌埗綾葷殑铏氬嚱鏁板湪瀛愮被鐨勮櫄鍑芥暟鍓嶉潰銆?/p>

 

鎴戠浉淇¤仾鏄庣殑浣犱竴瀹氬彲浠ュ弬鑰冨墠闈㈢殑閭d釜紼嬪簭錛屾潵緙栧啓涓孌電▼搴忔潵楠岃瘉銆?/p>

 

 

 

涓鑸戶鎵匡紙鏈夎櫄鍑芥暟瑕嗙洊錛?br> 

瑕嗙洊鐖剁被鐨勮櫄鍑芥暟鏄緢鏄劇劧鐨勪簨鎯咃紝涓嶇劧錛岃櫄鍑芥暟灝卞彉寰楁鏃犳剰涔夈備笅闈紝鎴戜滑鏉ョ湅涓涓嬶紝濡傛灉瀛愮被涓湁铏氬嚱鏁伴噸杞戒簡鐖剁被鐨勮櫄鍑芥暟錛屼細鏄竴涓粈涔堟牱瀛愶紵鍋囪錛屾垜浠湁涓嬮潰榪欐牱鐨勪竴涓戶鎵垮叧緋匯?/p>

 

 


 

涓轟簡璁╁ぇ瀹剁湅鍒拌緇ф壙榪囧悗鐨勬晥鏋滐紝鍦ㄨ繖涓被鐨勮璁′腑錛屾垜鍙鐩栦簡鐖剁被鐨勪竴涓嚱鏁幫細f()銆傞偅涔堬紝瀵逛簬媧劇敓綾葷殑瀹炰緥錛屽叾铏氬嚱鏁拌〃浼氭槸涓嬮潰鐨勪竴涓牱瀛愶細

 

 


 


鎴戜滑浠庤〃涓彲浠ョ湅鍒頒笅闈㈠嚑鐐癸紝

1錛夎鐩栫殑f()鍑芥暟琚斁鍒頒簡铏氳〃涓師鏉ョ埗綾昏櫄鍑芥暟鐨勪綅緗?/p>

2錛夋病鏈夎瑕嗙洊鐨勫嚱鏁頒緷鏃с?/p>

 

榪欐牱錛屾垜浠氨鍙互鐪嬪埌瀵逛簬涓嬮潰榪欐牱鐨勭▼搴忥紝

 

            Base *b = new Derive();

 

            b->f();

 

鐢眀鎵鎸囩殑鍐呭瓨涓殑铏氬嚱鏁拌〃鐨刦()鐨勪綅緗凡緇忚Derive::f()鍑芥暟鍦板潃鎵鍙栦唬錛屼簬鏄湪瀹為檯璋冪敤鍙戠敓鏃訛紝鏄疍erive::f()琚皟鐢ㄤ簡銆傝繖灝卞疄鐜頒簡澶氭併?/p>

 

 

 

澶氶噸緇ф壙錛堟棤铏氬嚱鏁拌鐩栵級
 

涓嬮潰錛屽啀璁╂垜浠潵鐪嬬湅澶氶噸緇ф壙涓殑鎯呭喌錛屽亣璁炬湁涓嬮潰榪欐牱涓涓被鐨勭戶鎵垮叧緋匯傛敞鎰忥細瀛愮被騫舵病鏈夎鐩栫埗綾葷殑鍑芥暟銆?/p>

 


 

 

瀵逛簬瀛愮被瀹炰緥涓殑铏氬嚱鏁拌〃錛屾槸涓嬮潰榪欎釜鏍峰瓙錛?/p>

 


 


鎴戜滑鍙互鐪嬪埌錛?/p>

1錛?nbsp; 姣忎釜鐖剁被閮芥湁鑷繁鐨勮櫄琛ㄣ?/p>

2錛?nbsp; 瀛愮被鐨勬垚鍛樺嚱鏁拌鏀懼埌浜嗙涓涓埗綾葷殑琛ㄤ腑銆傦紙鎵璋撶殑絎竴涓埗綾繪槸鎸夌収澹版槑欏哄簭鏉ュ垽鏂殑錛?/p>

 

榪欐牱鍋氬氨鏄負浜嗚В鍐充笉鍚岀殑鐖剁被綾誨瀷鐨勬寚閽堟寚鍚戝悓涓涓瓙綾誨疄渚嬶紝鑰岃兘澶熻皟鐢ㄥ埌瀹為檯鐨勫嚱鏁般?/p>

 

 

 

 

澶氶噸緇ф壙錛堟湁铏氬嚱鏁拌鐩栵級
 

涓嬮潰鎴戜滑鍐嶆潵鐪嬬湅錛屽鏋滃彂鐢熻櫄鍑芥暟瑕嗙洊鐨勬儏鍐點?/p>

 

涓嬪浘涓紝鎴戜滑鍦ㄥ瓙綾諱腑瑕嗙洊浜嗙埗綾葷殑f()鍑芥暟銆?/p>

 


 

 

涓嬮潰鏄浜庡瓙綾誨疄渚嬩腑鐨勮櫄鍑芥暟琛ㄧ殑鍥撅細

 

 


 

鎴戜滑鍙互鐪嬭錛屼笁涓埗綾昏櫄鍑芥暟琛ㄤ腑鐨刦()鐨勪綅緗鏇挎崲鎴愪簡瀛愮被鐨勫嚱鏁版寚閽堛傝繖鏍鳳紝鎴戜滑灝卞彲浠ヤ換涓闈欐佺被鍨嬬殑鐖剁被鏉ユ寚鍚戝瓙綾伙紝騫惰皟鐢ㄥ瓙綾葷殑f()浜嗐傚錛?/p>

 

            Derive d;

            Base1 *b1 = &d;

            Base2 *b2 = &d;

            Base3 *b3 = &d;

            b1->f(); //Derive::f()

            b2->f(); //Derive::f()

            b3->f(); //Derive::f()

 

            b1->g(); //Base1::g()

            b2->g(); //Base2::g()

            b3->g(); //Base3::g()

 

 

瀹夊叏鎬?br> 

姣忔鍐機++鐨勬枃绔狅紝鎬誨厤涓嶄簡瑕佹壒鍒や竴涓婥++銆傝繖綃囨枃绔犱篃涓嶄緥澶栥傞氳繃涓婇潰鐨勮榪幫紝鐩鎬俊鎴戜滑瀵硅櫄鍑芥暟琛ㄦ湁涓涓瘮杈冪粏鑷寸殑浜嗚В浜嗐傛按鍙澆鑸燂紝浜﹀彲瑕嗚垷銆備笅闈紝璁╂垜浠潵鐪嬬湅鎴戜滑鍙互鐢ㄨ櫄鍑芥暟琛ㄦ潵騫茬偣浠涔堝潖浜嬪惂銆?/p>

 

涓銆侀氳繃鐖剁被鍨嬬殑鎸囬拡璁塊棶瀛愮被鑷繁鐨勮櫄鍑芥暟

鎴戜滑鐭ラ亾錛屽瓙綾繪病鏈夐噸杞界埗綾葷殑铏氬嚱鏁版槸涓浠舵鏃犳剰涔夌殑浜嬫儏銆傚洜涓哄鎬佷篃鏄鍩轟簬鍑芥暟閲嶈澆鐨勩傝櫧鐒跺湪涓婇潰鐨勫浘涓垜浠彲浠ョ湅鍒癇ase1鐨勮櫄琛ㄤ腑鏈塂erive鐨勮櫄鍑芥暟錛屼絾鎴戜滑鏍規湰涓嶅彲鑳戒嬌鐢ㄤ笅闈㈢殑璇彞鏉ヨ皟鐢ㄥ瓙綾葷殑鑷湁铏氬嚱鏁幫細

 

          Base1 *b1 = new Derive();

            b1->f1();  //緙栬瘧鍑洪敊

 

浠諱綍濡勫浘浣跨敤鐖剁被鎸囬拡鎯寵皟鐢ㄥ瓙綾諱腑鐨勬湭瑕嗙洊鐖剁被鐨勬垚鍛樺嚱鏁扮殑琛屼負閮戒細琚紪璇戝櫒瑙嗕負闈炴硶錛屾墍浠ワ紝榪欐牱鐨勭▼搴忔牴鏈棤娉曠紪璇戦氳繃銆備絾鍦ㄨ繍琛屾椂錛屾垜浠彲浠ラ氳繃鎸囬拡鐨勬柟寮忚闂櫄鍑芥暟琛ㄦ潵杈懼埌榪濆弽C++璇箟鐨勮涓恒傦紙鍏充簬榪欐柟闈㈢殑灝濊瘯錛岄氳繃闃呰鍚庨潰闄勫綍鐨勪唬鐮侊紝鐩鎬俊浣犲彲浠ュ仛鍒拌繖涓鐐癸級

 

 

浜屻佽闂畁on-public鐨勮櫄鍑芥暟

鍙﹀錛屽鏋滅埗綾葷殑铏氬嚱鏁版槸private鎴栨槸protected鐨勶紝浣嗚繖浜涢潪public鐨勮櫄鍑芥暟鍚屾牱浼氬瓨鍦ㄤ簬铏氬嚱鏁拌〃涓紝鎵浠ワ紝鎴戜滑鍚屾牱鍙互浣跨敤璁塊棶铏氬嚱鏁拌〃鐨勬柟寮忔潵璁塊棶榪欎簺non-public鐨勮櫄鍑芥暟錛岃繖鏄緢瀹規槗鍋氬埌鐨勩?/p>

 

濡傦細

 

class Base {

    private:

            virtual void f() { cout << "Base::f" << endl; }

 

};

 

class Derive : public Base{

 

};

 

typedef void(*Fun)(void);

 

void main() {

    Derive d;

    Fun  pFun = (Fun)*((int*)*(int*)(&d)+0);

    pFun();

}

 

 

緇撴潫璇?br>C++榪欓棬璇█鏄竴闂∕agic鐨勮璦錛屽浜庣▼搴忓憳鏉ヨ錛屾垜浠技涔庢案榪滄懜涓嶆竻妤氳繖闂ㄨ璦鑳岀潃鎴戜滑鍦ㄥ共浜嗕粈涔堛傞渶瑕佺啛鎮夎繖闂ㄨ璦錛屾垜浠氨蹇呴渶瑕佷簡瑙++閲岄潰鐨勯偅浜涗笢瑗匡紝闇瑕佸幓浜嗚ВC++涓偅浜涘嵄闄╃殑涓滆タ銆備笉鐒訛紝榪欐槸涓縐嶆惉璧風煶澶寸牳鑷繁鑴氱殑緙栫▼璇█銆?/p>

 

鍦ㄦ枃绔犳潫涔嬪墠榪樻槸浠嬬粛涓涓嬭嚜宸卞惂銆傛垜浠庝簨杞歡鐮斿彂鏈夊崄涓勾澶翠簡錛岀洰鍓嶆槸杞歡寮鍙戞妧鏈富綆★紝鎶鏈柟闈紝涓繪敾Unix/C/C++錛屾瘮杈冨枩嬈㈢綉緇滀笂鐨勬妧鏈紝姣斿鍒嗗竷寮忚綆楋紝緗戞牸璁$畻錛孭2P錛孉jax絳変竴鍒囧拰浜掕仈緗戠浉鍏崇殑涓滆タ銆傜鐞嗘柟闈㈡瘮杈冩搮闀夸簬鍥㈤槦寤鴻錛屾妧鏈秼鍔垮垎鏋愶紝欏圭洰綆$悊銆傛榪庡ぇ瀹跺拰鎴戜氦嫻侊紝鎴戠殑MSN鍜孍mail鏄細haoel@hotmail.com 

 

闄勫綍涓錛歏C涓煡鐪嬭櫄鍑芥暟琛?br> 

鎴戜滑鍙互鍦╒C鐨処DE鐜涓殑Debug鐘舵佷笅灞曞紑綾葷殑瀹炰緥灝卞彲浠ョ湅鍒拌櫄鍑芥暟琛ㄤ簡錛堝茍涓嶆槸寰堝畬鏁寸殑錛?/p>

 

 

闄勫綍 浜岋細渚嬬▼
涓嬮潰鏄竴涓叧浜庡閲嶇戶鎵跨殑铏氬嚱鏁拌〃璁塊棶鐨勪緥紼嬶細

 

#include <iostream>

using namespace std;

 

class Base1 {

public:

            virtual void f() { cout << "Base1::f" << endl; }

            virtual void g() { cout << "Base1::g" << endl; }

            virtual void h() { cout << "Base1::h" << endl; }

 

};

 

class Base2 {

public:

            virtual void f() { cout << "Base2::f" << endl; }

            virtual void g() { cout << "Base2::g" << endl; }

            virtual void h() { cout << "Base2::h" << endl; }

};

 

class Base3 {

public:

            virtual void f() { cout << "Base3::f" << endl; }

            virtual void g() { cout << "Base3::g" << endl; }

            virtual void h() { cout << "Base3::h" << endl; }

};

 

 

class Derive : public Base1, public Base2, public Base3 {

public:

            virtual void f() { cout << "Derive::f" << endl; }

            virtual void g1() { cout << "Derive::g1" << endl; }

};

 

 

typedef void(*Fun)(void);

 

int main()

{

            Fun pFun = NULL;

 

            Derive d;

            int** pVtab = (int**)&d;

 

            //Base1's vtable

            //pFun = (Fun)*((int*)*(int*)((int*)&d+0)+0);

            pFun = (Fun)pVtab[0][0];

            pFun();

 

            //pFun = (Fun)*((int*)*(int*)((int*)&d+0)+1);

            pFun = (Fun)pVtab[0][1];

            pFun();

 

            //pFun = (Fun)*((int*)*(int*)((int*)&d+0)+2);

            pFun = (Fun)pVtab[0][2];

            pFun();

 

            //Derive's vtable

            //pFun = (Fun)*((int*)*(int*)((int*)&d+0)+3);

            pFun = (Fun)pVtab[0][3];

            pFun();

 

            //The tail of the vtable

            pFun = (Fun)pVtab[0][4];

            cout<<pFun<<endl;

 

 

            //Base2's vtable

            //pFun = (Fun)*((int*)*(int*)((int*)&d+1)+0);

            pFun = (Fun)pVtab[1][0];

            pFun();

 

            //pFun = (Fun)*((int*)*(int*)((int*)&d+1)+1);

            pFun = (Fun)pVtab[1][1];

            pFun();

 

            pFun = (Fun)pVtab[1][2];

            pFun();

 

            //The tail of the vtable

            pFun = (Fun)pVtab[1][3];

            cout<<pFun<<endl;

 

 

 

            //Base3's vtable

            //pFun = (Fun)*((int*)*(int*)((int*)&d+1)+0);

            pFun = (Fun)pVtab[2][0];

            pFun();

 

            //pFun = (Fun)*((int*)*(int*)((int*)&d+1)+1);

            pFun = (Fun)pVtab[2][1];

            pFun();

 

            pFun = (Fun)pVtab[2][2];

            pFun();

 

            //The tail of the vtable

            pFun = (Fun)pVtab[2][3];

            cout<<pFun<<endl;

 

            return 0;

}

 

鏈枃鏉ヨ嚜CSDN鍗氬錛岃漿杞借鏍囨槑鍑哄錛?a >http://blog.csdn.net/haoel/archive/2007/12/18/1948051.aspx



Sandy 2009-07-03 17:32 鍙戣〃璇勮
]]>
杞? C++ 瀵硅薄鐨勫唴瀛樺竷灞(涓?http://www.shnenglu.com/SpringSnow/articles/89178.htmlSandySandyFri, 03 Jul 2009 09:21:00 GMThttp://www.shnenglu.com/SpringSnow/articles/89178.htmlhttp://www.shnenglu.com/SpringSnow/comments/89178.htmlhttp://www.shnenglu.com/SpringSnow/articles/89178.html#Feedback0http://www.shnenglu.com/SpringSnow/comments/commentRss/89178.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/89178.htmlC++ 瀵硅薄鐨勫唴瀛樺竷灞(涓?

 

闄堢殦

http://blog.csdn.net/haoel

 

 

閲嶅緇ф壙
 

涓嬮潰鎴戜滑鍐嶆潵鐪嬬湅錛屽彂鐢熼噸澶嶇戶鎵跨殑鎯呭喌銆傛墍璋撻噸澶嶇戶鎵匡紝涔熷氨鏄煇涓熀綾昏闂存帴鍦伴噸澶嶇戶鎵夸簡澶氭銆?/p>

 

涓嬪浘鏄竴涓戶鎵垮浘錛屾垜浠噸杞戒簡鐖剁被鐨刦()鍑芥暟銆?/p>

 

 

 

鍏剁被緇ф壙鐨勬簮浠g爜濡備笅鎵紺恒傚叾涓紝姣忎釜綾婚兘鏈変袱涓彉閲忥紝涓涓槸鏁村艦錛?瀛楄妭錛夛紝涓涓槸瀛楃錛?瀛楄妭錛夛紝鑰屼笖榪樻湁鑷繁鐨勮櫄鍑芥暟錛岃嚜宸眔verwrite鐖剁被鐨勮櫄鍑芥暟銆傚瀛愮被D涓紝f()瑕嗙洊浜嗚秴綾葷殑鍑芥暟錛?f1() 鍜宖2() 瑕嗙洊浜嗗叾鐖剁被鐨勮櫄鍑芥暟錛孌f()涓鴻嚜宸辯殑铏氬嚱鏁般?/p>

 

class B

{

    public:

        int ib;

        char cb;

    public:

        B():ib(0),cb('B') {}

 

        virtual void f() { cout << "B::f()" << endl;}

        virtual void Bf() { cout << "B::Bf()" << endl;}

};

class B1 :  public B

{

    public:

        int ib1;

        char cb1;

    public:

        B1():ib1(11),cb1('1') {}

 

        virtual void f() { cout << "B1::f()" << endl;}

        virtual void f1() { cout << "B1::f1()" << endl;}

        virtual void Bf1() { cout << "B1::Bf1()" << endl;}

 

};

class B2:  public B

{

    public:

        int ib2;

        char cb2;

    public:

        B2():ib2(12),cb2('2') {}

 

        virtual void f() { cout << "B2::f()" << endl;}

        virtual void f2() { cout << "B2::f2()" << endl;}

        virtual void Bf2() { cout << "B2::Bf2()" << endl;}

       

};

 

class D : public B1, public B2

{

    public:

        int id;

        char cd;

    public:

        D():id(100),cd('D') {}

 

        virtual void f() { cout << "D::f()" << endl;}

        virtual void f1() { cout << "D::f1()" << endl;}

        virtual void f2() { cout << "D::f2()" << endl;}

        virtual void Df() { cout << "D::Df()" << endl;}

       

};

鎴戜滑鐢ㄦ潵瀛樺彇瀛愮被鍐呭瓨甯冨眬鐨勪唬鐮佸涓嬫墍紺猴細錛堝湪VC++ 2003鍜孏++ 3.4.4涓嬶級

    typedef void(*Fun)(void);

    int** pVtab = NULL;

    Fun pFun = NULL;

 

    D d;

    pVtab = (int**)&d;

    cout << "[0] D::B1::_vptr->" << endl;

    pFun = (Fun)pVtab[0][0];

    cout << "     [0] ";    pFun();

    pFun = (Fun)pVtab[0][1];

    cout << "     [1] ";    pFun();

    pFun = (Fun)pVtab[0][2];

    cout << "     [2] ";    pFun();

    pFun = (Fun)pVtab[0][3];

    cout << "     [3] ";    pFun();

    pFun = (Fun)pVtab[0][4];

    cout << "     [4] ";    pFun();

    pFun = (Fun)pVtab[0][5];

    cout << "     [5] 0x" << pFun << endl;

   

    cout << "[1] B::ib = " << (int)pVtab[1] << endl;

    cout << "[2] B::cb = " << (char)pVtab[2] << endl;

    cout << "[3] B1::ib1 = " << (int)pVtab[3] << endl;

    cout << "[4] B1::cb1 = " << (char)pVtab[4] << endl;

 

    cout << "[5] D::B2::_vptr->" << endl;

    pFun = (Fun)pVtab[5][0];

    cout << "     [0] ";    pFun();

    pFun = (Fun)pVtab[5][1];

    cout << "     [1] ";    pFun();

    pFun = (Fun)pVtab[5][2];

    cout << "     [2] ";    pFun();

    pFun = (Fun)pVtab[5][3];

    cout << "     [3] ";    pFun();

    pFun = (Fun)pVtab[5][4];

    cout << "     [4] 0x" << pFun << endl;

 

    cout << "[6] B::ib = " << (int)pVtab[6] << endl;

    cout << "[7] B::cb = " << (char)pVtab[7] << endl;   

    cout << "[8] B2::ib2 = " << (int)pVtab[8] << endl;

    cout << "[9] B2::cb2 = " << (char)pVtab[9] << endl;

 

    cout << "[10] D::id = " << (int)pVtab[10] << endl;

    cout << "[11] D::cd = " << (char)pVtab[11] << endl;

 

紼嬪簭榪愯緇撴灉濡備笅錛?/p>


 

GCC 3.4.4
 VC++ 2003
 
[0] D::B1::_vptr->

     [0] D::f()

     [1] B::Bf()

     [2] D::f1()

     [3] B1::Bf1()

     [4] D::f2()

     [5] 0x1

[1] B::ib = 0

[2] B::cb = B

[3] B1::ib1 = 11

[4] B1::cb1 = 1

[5] D::B2::_vptr->

     [0] D::f()

     [1] B::Bf()

     [2] D::f2()

     [3] B2::Bf2()

     [4] 0x0

[6] B::ib = 0

[7] B::cb = B

[8] B2::ib2 = 12

[9] B2::cb2 = 2

[10] D::id = 100

[11] D::cd = D
 [0] D::B1::_vptr->

     [0] D::f()

     [1] B::Bf()

     [2] D::f1()

     [3] B1::Bf1()

     [4] D::Df()

     [5] 0x00000000

[1] B::ib = 0

[2] B::cb = B

[3] B1::ib1 = 11

[4] B1::cb1 = 1

[5] D::B2::_vptr->

     [0] D::f()

     [1] B::Bf()

     [2] D::f2()

     [3] B2::Bf2()

     [4] 0x00000000

[6] B::ib = 0

[7] B::cb = B

[8] B2::ib2 = 12

[9] B2::cb2 = 2

[10] D::id = 100

[11] D::cd = D
 


 

涓嬮潰鏄浜庡瓙綾誨疄渚嬩腑鐨勮櫄鍑芥暟琛ㄧ殑鍥撅細

 


 

 


鎴戜滑鍙互鐪嬭錛屾渶欏剁鐨勭埗綾籅鍏舵垚鍛樺彉閲忓瓨鍦ㄤ簬B1鍜孊2涓紝騫惰D緇欑戶鎵夸笅鍘諱簡銆傝屽湪D涓紝鍏舵湁B1鍜孊2鐨勫疄渚嬶紝浜庢槸B鐨勬垚鍛樺湪D鐨勫疄渚嬩腑瀛樺湪涓や喚錛屼竴浠芥槸B1緇ф壙鑰屾潵鐨勶紝鍙︿竴浠芥槸B2緇ф壙鑰屾潵鐨勩傛墍浠ワ紝濡傛灉鎴戜滑浣跨敤浠ヤ笅璇彞錛屽垯浼氫駭鐢熶簩涔夋х紪璇戦敊璇細

 

D d;

d.ib = 0;               //浜屼箟鎬ч敊璇?/p>

d.B1::ib = 1;           //姝g‘

d.B2::ib = 2;           //姝g‘


娉ㄦ剰錛屼笂闈緥紼嬩腑鐨勬渶鍚庝袱鏉¤鍙ュ瓨鍙栫殑鏄袱涓彉閲忋傝櫧鐒舵垜浠秷闄や簡浜屼箟鎬х殑緙栬瘧閿欒錛屼絾B綾誨湪D涓繕鏄湁涓や釜瀹炰緥錛岃繖縐嶇戶鎵塊犳垚浜嗘暟鎹殑閲嶅錛屾垜浠彨榪欑緇ф壙涓洪噸澶嶇戶鎵褲傞噸澶嶇殑鍩虹被鏁版嵁鎴愬憳鍙兘騫朵笉鏄垜浠兂瑕佺殑銆傛墍浠ワ紝C++寮曞叆浜嗚櫄鍩虹被鐨勬蹇點?/p>

 

 

閽葷煶鍨嬪閲嶈櫄鎷熺戶鎵?br> 

铏氭嫙緇ф壙鐨勫嚭鐜板氨鏄負浜嗚В鍐抽噸澶嶇戶鎵夸腑澶氫釜闂存帴鐖剁被鐨勯棶棰樼殑銆傞捇鐭沖瀷鐨勭粨鏋勬槸鍏舵渶緇忓吀鐨勭粨鏋勩備篃鏄垜浠湪榪欓噷瑕佽璁虹殑緇撴瀯錛?/p>

 

涓婅堪鐨?#8220;閲嶅緇ф壙”鍙渶瑕佹妸B1鍜孊2緇ф壙B鐨勮娉曚腑鍔犱笂virtual 鍏抽敭錛屽氨鎴愪簡铏氭嫙緇ф壙錛屽叾緇ф壙鍥懼涓嬫墍紺猴細

 

 

 

 

涓婂浘鍜屽墠闈㈢殑“閲嶅緇ф壙”涓殑綾葷殑鍐呴儴鏁版嵁鍜屾帴鍙i兘鏄畬鍏ㄤ竴鏍風殑錛屽彧鏄垜浠噰鐢ㄤ簡铏氭嫙緇ф壙錛氬叾鐪佺暐鍚庣殑婧愮爜濡備笅鎵紺猴細

 

class B {……};

class B1 : virtual public B{……};

class B2: virtual public B{……};

class D : public B1, public B2{ …… };

 

鍦ㄦ煡鐪婦涔嬪墠錛屾垜浠厛鐪嬩竴鐪嬪崟涓铏氭嫙緇ф壙鐨勬儏鍐點備笅闈㈡槸涓孌靛湪VC++2003涓嬬殑嫻嬭瘯紼嬪簭錛氾紙鍥犱負VC++鍜孏CC鐨勫唴瀛樿屽眬涓婃湁涓浜涚粏鑺備笂鐨勪笉鍚岋紝鎵浠ヨ繖閲屽彧緇欏嚭VC++鐨勭▼搴忥紝GCC涓嬬殑紼嬪簭澶у鍙互鏍規嵁鎴戠粰鍑虹殑紼嬪簭鑷繁浠跨収鐫鍐欎竴涓幓璇曚竴璇曪級錛?/p>

 

    int** pVtab = NULL;

    Fun pFun = NULL;

 

    B1 bb1;

 

    pVtab = (int**)&bb1;

    cout << "[0] B1::_vptr->" << endl;

    pFun = (Fun)pVtab[0][0];

    cout << "     [0] ";

    pFun(); //B1::f1();

    cout << "     [1] ";

    pFun = (Fun)pVtab[0][1];

    pFun(); //B1::bf1();

    cout << "     [2] ";

    cout << pVtab[0][2] << endl;

 

    cout << "[1] = 0x";

    cout << (int*)*((int*)(&bb1)+1) <<endl; //B1::ib1

    cout << "[2] B1::ib1 = ";

    cout << (int)*((int*)(&bb1)+2) <<endl; //B1::ib1

    cout << "[3] B1::cb1 = ";

    cout << (char)*((int*)(&bb1)+3) << endl; //B1::cb1

 

    cout << "[4] = 0x";

    cout << (int*)*((int*)(&bb1)+4) << endl; //NULL

 

    cout << "[5] B::_vptr->" << endl;

    pFun = (Fun)pVtab[5][0];

    cout << "     [0] ";

    pFun(); //B1::f();

    pFun = (Fun)pVtab[5][1];

    cout << "     [1] ";

    pFun(); //B::Bf();

    cout << "     [2] ";

    cout << "0x" << (Fun)pVtab[5][2] << endl;

 

    cout << "[6] B::ib = ";

    cout << (int)*((int*)(&bb1)+6) <<endl; //B::ib

    cout << "[7] B::cb = ";

 

鍏惰繍琛岀粨鏋滃涓嬶紙鎴戠粨鍑轟簡GCC鐨勫拰VC++2003鐨勫姣旓級錛?/p>

 

GCC 3.4.4
 VC++ 2003
 
[0] B1::_vptr ->

    [0] : B1::f()

    [1] : B1::f1()

    [2] : B1::Bf1()

    [3] : 0

[1] B1::ib1 : 11

[2] B1::cb1 : 1

[3] B::_vptr ->

    [0] : B1::f()

    [1] : B::Bf()

    [2] : 0

[4] B::ib : 0

[5] B::cb : B

[6] NULL : 0
 [0] B1::_vptr->

     [0] B1::f1()

     [1] B1::Bf1()

     [2] 0

[1] = 0x00454310 ç璇ュ湴鍧鍙栧煎悗鏄?4

[2] B1::ib1 = 11

[3] B1::cb1 = 1

[4] = 0x00000000

[5] B::_vptr->

     [0] B1::f()

     [1] B::Bf()

     [2] 0x00000000

[6] B::ib = 0

[7] B::cb = B
 

 

 

榪欓噷錛屽ぇ瀹跺彲浠ヨ嚜宸卞姣斾竴涓嬨傚叧浜庣粏鑺備笂錛屾垜浼氬湪鍚庨潰涓騫跺啀璇淬?/p>

 

涓嬮潰鐨勬祴璇曠▼搴忔槸鐪嬪瓙綾籇鐨勫唴瀛樺竷灞錛屽悓鏍鋒槸VC++ 2003鐨勶紙鍥犱負VC++鍜孏CC鐨勫唴瀛樺竷灞涓婃湁涓浜涚粏鑺備笂鐨勪笉鍚岋紝鑰孷C++鐨勭浉瀵硅娓呮寰堝錛屾墍浠ヨ繖閲屽彧緇欏嚭VC++鐨勭▼搴忥紝GCC涓嬬殑紼嬪簭澶у鍙互鏍規嵁鎴戠粰鍑虹殑紼嬪簭鑷繁浠跨収鐫鍐欎竴涓幓璇曚竴璇曪級錛?/p>

 

    D d;

 

    pVtab = (int**)&d;

    cout << "[0] D::B1::_vptr->" << endl;

    pFun = (Fun)pVtab[0][0];

    cout << "     [0] ";    pFun(); //D::f1();

    pFun = (Fun)pVtab[0][1];

    cout << "     [1] ";    pFun(); //B1::Bf1();

    pFun = (Fun)pVtab[0][2];

    cout << "     [2] ";    pFun(); //D::Df();

    pFun = (Fun)pVtab[0][3];

    cout << "     [3] ";

    cout << pFun << endl;

 

    //cout << pVtab[4][2] << endl;

    cout << "[1] = 0x";

    cout <<  (int*)((&dd)+1) <<endl; //????

 

    cout << "[2] B1::ib1 = ";

    cout << *((int*)(&dd)+2) <<endl; //B1::ib1

    cout << "[3] B1::cb1 = ";

    cout << (char)*((int*)(&dd)+3) << endl; //B1::cb1

 

    //---------------------

    cout << "[4] D::B2::_vptr->" << endl;

    pFun = (Fun)pVtab[4][0];

    cout << "     [0] ";    pFun(); //D::f2();

    pFun = (Fun)pVtab[4][1];

    cout << "     [1] ";    pFun(); //B2::Bf2();

    pFun = (Fun)pVtab[4][2];

    cout << "     [2] ";

    cout << pFun << endl;

   

    cout << "[5] = 0x";

    cout << *((int*)(&dd)+5) << endl; // ???

 

    cout << "[6] B2::ib2 = ";

    cout << (int)*((int*)(&dd)+6) <<endl; //B2::ib2

    cout << "[7] B2::cb2 = ";

    cout << (char)*((int*)(&dd)+7) << endl; //B2::cb2

 

    cout << "[8] D::id = ";

    cout << *((int*)(&dd)+8) << endl; //D::id

    cout << "[9] D::cd = ";

    cout << (char)*((int*)(&dd)+9) << endl;//D::cd

 

    cout << "[10]  = 0x";

    cout << (int*)*((int*)(&dd)+10) << endl;

    //---------------------

    cout << "[11] D::B::_vptr->" << endl;

    pFun = (Fun)pVtab[11][0];

    cout << "     [0] ";    pFun(); //D::f();

    pFun = (Fun)pVtab[11][1];

    cout << "     [1] ";    pFun(); //B::Bf();

    pFun = (Fun)pVtab[11][2];

    cout << "     [2] ";

    cout << pFun << endl;

 

    cout << "[12] B::ib = ";

    cout << *((int*)(&dd)+12) << endl; //B::ib

    cout << "[13] B::cb = ";

    cout << (char)*((int*)(&dd)+13) <<endl;//B::cb

 

涓嬮潰緇欏嚭榪愯鍚庣殑緇撴灉錛堝垎VC++鍜孏CC涓ら儴浠斤級

 

 

GCC 3.4.4
 VC++ 2003
 
[0] B1::_vptr ->

    [0] : D::f()

    [1] : D::f1()

    [2] : B1::Bf1()

    [3] : D::f2()

    [4] : D::Df()

    [5] : 1

[1] B1::ib1 : 11

[2] B1::cb1 : 1

[3] B2::_vptr ->

    [0] : D::f()

    [1] : D::f2()

    [2] : B2::Bf2()

    [3] : 0

[4] B2::ib2 : 12

[5] B2::cb2 : 2

[6] D::id : 100

[7] D::cd : D

[8] B::_vptr ->

    [0] : D::f()

    [1] : B::Bf()

    [2] : 0

[9] B::ib : 0

[10] B::cb : B

[11] NULL : 0
 [0] D::B1::_vptr->

     [0] D::f1()

     [1] B1::Bf1()

     [2] D::Df()

     [3] 00000000

[1] = 0x0013FDC4  ç 璇ュ湴鍧鍙栧煎悗鏄?4

[2] B1::ib1 = 11

[3] B1::cb1 = 1

[4] D::B2::_vptr->

     [0] D::f2()

     [1] B2::Bf2()

     [2] 00000000

[5] = 0x4539260   ç 璇ュ湴鍧鍙栧煎悗鏄?4

[6] B2::ib2 = 12

[7] B2::cb2 = 2

[8] D::id = 100

[9] D::cd = D

[10]  = 0x00000000

[11] D::B::_vptr->

     [0] D::f()

     [1] B::Bf()

     [2] 00000000

[12] B::ib = 0

[13] B::cb = B
 


 

 

鍏充簬铏氭嫙緇ф壙鐨勮繍琛岀粨鏋滄垜灝變笉鐢誨浘浜嗭紙鍓嶉潰鐨勪綔鍥懼凡緇忚鎴戜駭鐢熶簡寰堜弗閲嶇殑鍘屽︽劅錛屾墍浠ュ氨鍋蜂釜鎳掍簡錛屽ぇ瀹惰璋呬簡錛?/p>

 

鍦ㄤ笂闈㈢殑杈撳嚭緇撴灉涓紝鎴戠敤涓嶅悓鐨勯鑹插仛浜嗕竴浜涙爣鏄庛傛垜浠彲浠ョ湅鍒板涓嬬殑鍑犵偣錛?/p>

 

1錛夋棤璁烘槸GCC榪樻槸VC++錛岄櫎浜嗕竴浜涚粏鑺備笂鐨勪笉鍚岋紝鍏跺ぇ浣撲笂鐨勫璞″竷灞鏄竴鏍風殑銆備篃灝辨槸璇達紝鍏堟槸B1錛堥粍鑹詫級錛岀劧鍚庢槸B2錛堢豢鑹詫級錛屾帴鐫鏄疍錛堢伆鑹詫級錛岃孊榪欎釜瓚呯被錛堥潚钃濊壊錛夌殑瀹炰緥閮芥斁鍦ㄦ渶鍚庣殑浣嶇疆銆?/p>

 

2錛夊叧浜庤櫄鍑芥暟琛紝灝ゅ叾鏄涓涓櫄琛紝GCC鍜孷C++鏈夊緢閲嶅ぇ鐨勪笉涓鏍楓備絾浠旂粏鐪嬩笅鏉ワ紝榪樻槸VC++鐨勮櫄琛ㄦ瘮杈冩竻鏅板拰鏈夐昏緫鎬с?/p>

 

3錛塚C++鍜孏CC閮芥妸B榪欎釜瓚呯被鏀懼埌浜嗘渶鍚庯紝鑰孷C++鏈変竴涓狽ULL鍒嗛殧絎︽妸B鍜孊1鍜孊2鐨勫竷灞鍒嗗紑銆侴CC鍒欐病鏈夈?/p>

 

4錛塚C++涓殑鍐呭瓨甯冨眬鏈変袱涓湴鍧鎴戞湁浜涗笉鏄緢鏄庣櫧錛屽湪鍏朵腑鎴戠敤綰㈣壊鏍囧嚭浜嗐傚彇鍏跺唴瀹規槸-4銆傛帴閬撶悊鏉ヨ錛岃繖涓寚閽堝簲璇ユ槸鎸囧悜B綾誨疄渚嬬殑鍐呭瓨鍦板潃錛堣繖涓仛娉曞氨鏄負浜嗕繚璇侀噸澶嶇殑鐖剁被鍙湁涓涓疄渚嬬殑鎶鏈級銆備絾鍙栧煎悗鍗翠笉鏄傝繖鐐規垜鐩墠榪樺茍涓嶅お娓呮錛岃繕鍚戝ぇ瀹惰鏁欍?/p>

 

5錛塆CC鐨勫唴瀛樺竷灞涓湪B1鍜孊2涓垯娌℃湁鎸囧悜B鐨勬寚閽堛傝繖鐐瑰彲浠ョ悊瑙o紝緙栬瘧鍣ㄥ彲浠ラ氳繃璁$畻B1鍜孊2鐨剆ize鑰屽緱鍑築鐨勫亸縐婚噺銆?/p>

 

 

緇撴潫璇?br>C++榪欓棬璇█鏄竴闂ㄦ瘮杈冨鏉傜殑璇█錛屽浜庣▼搴忓憳鏉ヨ錛屾垜浠技涔庢案榪滄懜涓嶆竻妤氳繖闂ㄨ璦鑳岀潃鎴戜滑鍦ㄥ共浜嗕粈涔堛傞渶瑕佺啛鎮夎繖闂ㄨ璦錛屾垜浠氨蹇呴渶瑕佷簡瑙++閲岄潰鐨勯偅浜涗笢瑗匡紝闇瑕佹垜浠幓浜嗚В浠栧悗闈㈢殑鍐呭瓨瀵硅薄銆傝繖鏍鋒垜浠墠鑳界湡姝g殑浜嗚ВC++錛屼粠鑰岃兘澶熸洿濂界殑浣跨敤C++榪欓棬鏈闅劇殑緙栫▼璇█銆?/p>

 

鍦ㄦ枃绔犳潫涔嬪墠榪樻槸浠嬬粛涓涓嬭嚜宸卞惂銆傛垜浠庝簨杞歡鐮斿彂鏈夊崄涓勾澶翠簡錛岀洰鍓嶆槸杞歡寮鍙戞妧鏈富綆★紝鎶鏈柟闈紝涓繪敾Unix/C/C++錛屾瘮杈冨枩嬈㈢綉緇滀笂鐨勬妧鏈紝姣斿鍒嗗竷寮忚綆楋紝緗戞牸璁$畻錛孭2P錛孉jax絳変竴鍒囧拰浜掕仈緗戠浉鍏崇殑涓滆タ銆傜鐞嗘柟闈㈡瘮杈冩搮闀夸簬鍥㈤槦寤鴻錛屾妧鏈秼鍔垮垎鏋愶紝欏圭洰綆$悊銆傛榪庡ぇ瀹跺拰鎴戜氦嫻侊紝鎴戠殑MSN鍜孍mail鏄細haoel@hotmail.


鏈枃鏉ヨ嚜CSDN鍗氬錛岃漿杞借鏍囨槑鍑哄錛?a >http://blog.csdn.net/haoel/archive/2008/10/15/3081385.aspx



Sandy 2009-07-03 17:21 鍙戣〃璇勮
]]>
杞? C++ 瀵硅薄鐨勫唴瀛樺竷灞(涓?http://www.shnenglu.com/SpringSnow/articles/89177.htmlSandySandyFri, 03 Jul 2009 09:20:00 GMThttp://www.shnenglu.com/SpringSnow/articles/89177.htmlhttp://www.shnenglu.com/SpringSnow/comments/89177.htmlhttp://www.shnenglu.com/SpringSnow/articles/89177.html#Feedback0http://www.shnenglu.com/SpringSnow/comments/commentRss/89177.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/89177.html濂芥枃绔?灝辨曟壘涓嶅埌浜?鍏堣漿鍒拌繖閲?濂戒互鍚庢弧婊″搧璇?

C++ 瀵硅薄鐨勫唴瀛樺竷灞(涓?

 

闄堢殦

http://blog.csdn.net/haoel

 

鍓嶈█
 

07騫?2鏈堬紝鎴戝啓浜嗕竴綃囥奀++铏氬嚱鏁拌〃瑙f瀽銆嬬殑鏂囩珷錛屽紩璧蜂簡澶у鐨勫叴瓚c傛湁寰堝鏈嬪弸瀵規垜鐨勬枃绔犵暀浜嗚█錛屾湁榧撳姳鎴戠殑錛屾湁鎵硅瘎鎴戠殑錛岃繕鏈夊緢澶氶棶闂鐨勩傛垜鍦ㄨ繖閲屼竴騫跺澶у鐨勭暀璦琛ㄧず鎰熻阿銆傝繖涔熸槸鎴戜負浠涔堝啀鍐欎竴綃囩畫璦鐨勫師鍥犮傚洜涓猴紝鍦ㄤ笂涓綃囨枃绔犱腑錛屾垜鐢ㄤ簡鐨勭ず渚嬮兘鏄潪甯哥畝鍗曠殑錛屼富瑕佹槸涓轟簡璇存槑涓浜涙満鐞嗕笂鐨勯棶棰橈紝涔熸槸涓轟簡鍥句竴浜涜〃杈句笂鏂逛究鍜岀畝鍗曘備笉鎯籌紝榪欑瘒鏂囩珷鎴愪負浜嗘墦寮C++瀵硅薄妯″瀷鍐呭瓨甯冨眬鐨勪竴涓紩瀛愶紝寮曞彂浜嗗ぇ瀹跺C++瀵硅薄鐨勬洿娣卞眰嬈$殑璁ㄨ銆傚綋鐒訛紝鎴戜箣鍓嶇殑鏂囩珷榪樻湁寰堝鏂歸潰娌℃湁娑夊強錛屼粠鎴戜釜浜烘劅瑙変笅鏉ワ紝鍦ㄨ皥璁鴻櫄鍑芥暟琛ㄩ噷錛岃嚦灝戞湁浠ヤ笅榪欎簺鍐呭娌℃湁娑夊強錛?/p>

 

1錛夋湁鎴愬憳鍙橀噺鐨勬儏鍐點?/p>

2錛夋湁閲嶅緇ф壙鐨勬儏鍐點?/p>

3錛夋湁铏氭嫙緇ф壙鐨勬儏鍐點?/p>

4錛夋湁閽葷煶鍨嬭櫄鎷熺戶鎵跨殑鎯呭喌銆?/p>

 

榪欎簺閮芥槸鎴戞湰綃囨枃绔犻渶瑕佸悜澶у璇存槑鐨勪笢瑗褲傛墍浠ワ紝榪欑瘒鏂囩珷灝嗕細鏄奀++铏氬嚱鏁拌〃瑙f瀽銆嬬殑涓涓畫綃囷紝涔熸槸涓綃囬珮綰ц繘闃剁殑鏂囩珷銆傛垜甯屾湜澶у鍦ㄨ榪欑瘒鏂囩珷涔嬪墠瀵笴++鏈変竴瀹氱殑鍩虹鍜屼簡瑙o紝騫惰兘鍏堣鎴戠殑涓婁竴綃囨枃绔犮傚洜涓鴻繖綃囨枃绔犵殑娣卞害鍙兘浼氭瘮杈冩繁錛岃屼笖浼氭瘮杈冩潅涔憋紝鎴戝笇鏈涗綘鍦ㄨ鏈瘒鏂囩珷鏃朵笉浼氭湁澶ц剳鎬濈淮绱婁貢瀵艱嚧澶ц剳姝繪満鐨勬儏鍐點?-)

 

瀵硅薄鐨勫獎鍝嶅洜绱?br> 

綆鑰岃█涔嬶紝鎴戜滑涓涓被鍙兘浼氭湁濡備笅鐨勫獎鍝嶅洜绱狅細

 

1錛夋垚鍛樺彉閲?/p>

2錛夎櫄鍑芥暟錛堜駭鐢熻櫄鍑芥暟琛級

3錛夊崟涓緇ф壙錛堝彧緇ф壙浜庝竴涓被錛?/p>

4錛夊閲嶇戶鎵匡紙緇ф壙澶氫釜綾伙級

5錛夐噸澶嶇戶鎵匡紙緇ф壙鐨勫涓埗綾諱腑鍏剁埗綾繪湁鐩稿悓鐨勮秴綾伙級

6錛夎櫄鎷熺戶鎵匡紙浣跨敤virtual鏂瑰紡緇ф壙錛屼負浜嗕繚璇佺戶鎵垮悗鐖剁被鐨勫唴瀛樺竷灞鍙細瀛樺湪涓浠斤級

涓婅堪鐨勪笢瑗塊氬父鏄疌++榪欓棬璇█鍦ㄨ涔夋柟闈㈠瀵硅薄鍐呴儴鐨勫獎鍝嶅洜绱狅紝褰撶劧錛岃繕浼氭湁緙栬瘧鍣ㄧ殑褰卞搷錛堟瘮濡備紭鍖栵級錛岃繕鏈夊瓧鑺傚榻愮殑褰卞搷銆傚湪榪欓噷鎴戜滑閮戒笉璁ㄨ錛屾垜浠彧璁ㄨC++璇█涓婄殑褰卞搷銆?/p>

 

鏈瘒鏂囩珷鐫閲嶈璁轟笅榪板嚑涓儏鍐典笅鐨凜++瀵硅薄鐨勫唴瀛樺竷灞鎯呭喌銆?/p>

 

1錛夊崟涓鐨勪竴鑸戶鎵匡紙甯︽垚鍛樺彉閲忋佽櫄鍑芥暟銆佽櫄鍑芥暟瑕嗙洊錛?/p>

2錛夊崟涓鐨勮櫄鎷熺戶鎵匡紙甯︽垚鍛樺彉閲忋佽櫄鍑芥暟銆佽櫄鍑芥暟瑕嗙洊錛?/p>

3錛夊閲嶇戶鎵匡紙甯︽垚鍛樺彉閲忋佽櫄鍑芥暟銆佽櫄鍑芥暟瑕嗙洊錛?/p>

4錛夐噸澶嶅閲嶇戶鎵匡紙甯︽垚鍛樺彉閲忋佽櫄鍑芥暟銆佽櫄鍑芥暟瑕嗙洊錛?/p>

5錛夐捇鐭沖瀷鐨勮櫄鎷熷閲嶇戶鎵匡紙甯︽垚鍛樺彉閲忋佽櫄鍑芥暟銆佽櫄鍑芥暟瑕嗙洊錛?/p>

 

鎴戜滑鐨勭洰鏍囧氨鏄紝璁╀簨鎯呰秺鏉ヨ秺澶嶆潅銆?/p>

 

鐭ヨ瘑澶嶄範
 

鎴戜滑綆鍗曞湴澶嶄範涓涓嬶紝鎴戜滑鍙互閫氳繃瀵硅薄鐨勫湴鍧鏉ュ彇寰楄櫄鍑芥暟琛ㄧ殑鍦板潃錛屽錛?/p>

 

          typedef void(*Fun)(void);

 

            Base b;

 

            Fun pFun = NULL;

 

            cout << "铏氬嚱鏁拌〃鍦板潃錛? << (int*)(&b) << endl;

            cout << "铏氬嚱鏁拌〃 鈥?絎竴涓嚱鏁板湴鍧錛? << (int*)*(int*)(&b) << endl;

 

            // Invoke the first virtual function 

            pFun = (Fun)*((int*)*(int*)(&b));

            pFun();

 

鎴戜滑鍚屾牱鍙互鐢ㄨ繖縐嶆柟寮忔潵鍙栧緱鏁翠釜瀵硅薄瀹炰緥鐨勫唴瀛樺竷灞銆傚洜涓鴻繖浜涗笢瑗垮湪鍐呭瓨涓兘鏄繛緇垎甯冪殑錛屾垜浠彧闇瑕佷嬌鐢ㄩ傚綋鐨勫湴鍧鍋忕Щ閲忥紝鎴戜滑灝卞彲浠ヨ幏寰楁暣涓唴瀛樺璞$殑甯冨眬銆?/p>

 

鏈瘒鏂囩珷涓殑渚嬬▼鎴栧唴瀛樺竷灞涓昏浣跨敤濡備笅緙栬瘧鍣ㄥ拰緋葷粺錛?/p>

1錛塛indows XP 鍜?VC++ 2003

2錛塁ygwin 鍜?G++ 3.4.4

 

鍗曚竴鐨勪竴鑸戶鎵?br> 

涓嬮潰錛屾垜浠亣璁炬湁濡備笅鎵紺虹殑涓涓戶鎵垮叧緋伙細

 

 


 

璇鋒敞鎰忥紝鍦ㄨ繖涓戶鎵垮叧緋諱腑錛岀埗綾伙紝瀛愮被錛屽瓩瀛愮被閮芥湁鑷繁鐨勪竴涓垚鍛樺彉閲忋傝屼簡綾昏鐩栦簡鐖剁被鐨刦()鏂規硶錛屽瓩瀛愮被瑕嗙洊浜嗗瓙綾葷殑g_child()鍙婂叾瓚呯被鐨刦()銆?/p>

 

鎴戜滑鐨勬簮紼嬪簭濡備笅鎵紺猴細

 

class Parent {

public:

    int iparent;

    Parent ():iparent (10) {}

    virtual void f() { cout << " Parent::f()" << endl; }

    virtual void g() { cout << " Parent::g()" << endl; }

    virtual void h() { cout << " Parent::h()" << endl; }

 

};

 

class Child : public Parent {

public:

    int ichild;

    Child():ichild(100) {}

    virtual void f() { cout << "Child::f()" << endl; }

    virtual void g_child() { cout << "Child::g_child()" << endl; }

    virtual void h_child() { cout << "Child::h_child()" << endl; }

};

 

class GrandChild : public Child{

public:

    int igrandchild;

    GrandChild():igrandchild(1000) {}

    virtual void f() { cout << "GrandChild::f()" << endl; }

    virtual void g_child() { cout << "GrandChild::g_child()" << endl; }

    virtual void h_grandchild() { cout << "GrandChild::h_grandchild()" << endl; }

};

鎴戜滑浣跨敤浠ヤ笅紼嬪簭浣滀負嫻嬭瘯紼嬪簭錛氾紙涓嬮潰紼嬪簭涓紝鎴戜嬌鐢ㄤ簡涓涓猧nt** pVtab 鏉ヤ綔涓洪亶鍘嗗璞″唴瀛樺竷灞鐨勬寚閽堬紝榪欐牱錛屾垜灝卞彲浠ユ柟渚垮湴鍍忎嬌鐢ㄦ暟緇勪竴鏍鋒潵閬嶅巻鎵鏈夌殑鎴愬憳鍖呮嫭鍏惰櫄鍑芥暟琛ㄤ簡錛屽湪鍚庨潰鐨勭▼搴忎腑錛屾垜涔熸槸鐢ㄨ繖鏍風殑鏂規硶鐨勶紝璇蜂笉蹇呮劅鍒板鎬紝錛?/p>

 

    typedef void(*Fun)(void);

 

    GrandChild gc;

   

 

    int** pVtab = (int**)&gc;

 

    cout << "[0] GrandChild::_vptr->" << endl;

    for (int i=0; (Fun)pVtab[0][i]!=NULL; i++){

                pFun = (Fun)pVtab[0][i];

                cout << "    ["<<i<<"] ";

                pFun();

    }

    cout << "[1] Parent.iparent = " << (int)pVtab[1] << endl;

    cout << "[2] Child.ichild = " << (int)pVtab[2] << endl;

    cout << "[3] GrandChild.igrandchild = " << (int)pVtab[3] << endl;

 

鍏惰繍琛岀粨鏋滃涓嬫墍紺猴細錛堝湪VC++ 2003鍜孏++ 3.4.4涓嬶級

 

[0] GrandChild::_vptr->

    [0] GrandChild::f()

    [1] Parent::g()

    [2] Parent::h()

    [3] GrandChild::g_child()

    [4] Child::h1()

    [5] GrandChild::h_grandchild()

[1] Parent.iparent = 10

[2] Child.ichild = 100

[3] GrandChild.igrandchild = 1000
 

 

浣跨敤鍥劇墖琛ㄧず濡備笅錛?/p>


 

 

 

 

鍙浠ヤ笅鍑犱釜鏂歸潰錛?/p>

1錛夎櫄鍑芥暟琛ㄥ湪鏈鍓嶉潰鐨勪綅緗?/p>

2錛夋垚鍛樺彉閲忔牴鎹叾緇ф壙鍜屽0鏄庨『搴忎緷嬈℃斁鍦ㄥ悗闈€?/p>

3錛夊湪鍗曚竴鐨勭戶鎵夸腑錛岃overwrite鐨勮櫄鍑芥暟鍦ㄨ櫄鍑芥暟琛ㄤ腑寰楀埌浜嗘洿鏂般?/p>

 

 

 

 

 

澶氶噸緇ф壙
 

涓嬮潰錛屽啀璁╂垜浠潵鐪嬬湅澶氶噸緇ф壙涓殑鎯呭喌錛屽亣璁炬湁涓嬮潰榪欐牱涓涓被鐨勭戶鎵垮叧緋匯傛敞鎰忥細瀛愮被鍙猳verwrite浜嗙埗綾葷殑f()鍑芥暟錛岃岃繕鏈変竴涓槸鑷繁鐨勫嚱鏁幫紙鎴戜滑榪欐牱鍋氱殑鐩殑鏄負浜嗙敤g1()浣滀負涓涓爣璁版潵鏍囨槑瀛愮被鐨勮櫄鍑芥暟琛級銆傝屼笖姣忎釜綾諱腑閮芥湁涓涓嚜宸辯殑鎴愬憳鍙橀噺錛?/p>

 


 

 

鎴戜滑鐨勭被緇ф壙鐨勬簮浠g爜濡備笅鎵紺猴細鐖剁被鐨勬垚鍛樺垵濮嬩負10錛?0錛?0錛屽瓙綾葷殑涓?00

 

class Base1 {

public:

    int ibase1;

    Base1():ibase1(10) {}

    virtual void f() { cout << "Base1::f()" << endl; }

    virtual void g() { cout << "Base1::g()" << endl; }

    virtual void h() { cout << "Base1::h()" << endl; }

 

};

 

class Base2 {

public:

    int ibase2;

    Base2():ibase2(20) {}

    virtual void f() { cout << "Base2::f()" << endl; }

    virtual void g() { cout << "Base2::g()" << endl; }

    virtual void h() { cout << "Base2::h()" << endl; }

};

 

class Base3 {

public:

    int ibase3;

    Base3():ibase3(30) {}

    virtual void f() { cout << "Base3::f()" << endl; }

    virtual void g() { cout << "Base3::g()" << endl; }

    virtual void h() { cout << "Base3::h()" << endl; }

};

 

 

class Derive : public Base1, public Base2, public Base3 {

public:

    int iderive;

    Derive():iderive(100) {}

    virtual void f() { cout << "Derive::f()" << endl; }

    virtual void g1() { cout << "Derive::g1()" << endl; }

};

 

鎴戜滑閫氳繃涓嬮潰鐨勭▼搴忔潵鏌ョ湅瀛愮被瀹炰緥鐨勫唴瀛樺竷灞錛氫笅闈㈢▼搴忎腑錛屾敞鎰忔垜浣跨敤浜嗕竴涓猻鍙橀噺錛屽叾涓敤鍒頒簡sizof(Base)鏉ユ壘涓嬩竴涓被鐨勫亸縐婚噺銆傦紙鍥犱負鎴戝0鏄庣殑鏄痠nt鎴愬憳錛屾墍浠ユ槸4涓瓧鑺傦紝鎵浠ユ病鏈夊榻愰棶棰樸傚叧浜庡唴瀛樼殑瀵歸綈闂錛屽ぇ瀹跺彲浠ヨ嚜琛岃瘯楠岋紝鎴戝湪榪欓噷灝變笉澶氳浜嗭級

 

             typedef void(*Fun)(void);

 

               Derive d;

 

                int** pVtab = (int**)&d;

 

                cout << "[0] Base1::_vptr->" << endl;

                pFun = (Fun)pVtab[0][0];

                cout << "     [0] ";

                pFun();

 

                pFun = (Fun)pVtab[0][1];

                cout << "     [1] ";pFun();

 

                pFun = (Fun)pVtab[0][2];

                cout << "     [2] ";pFun();

 

                pFun = (Fun)pVtab[0][3];

                cout << "     [3] "; pFun();

 

                pFun = (Fun)pVtab[0][4];

                cout << "     [4] "; cout<<pFun<<endl;

 

                cout << "[1] Base1.ibase1 = " << (int)pVtab[1] << endl;

 

 

                int s = sizeof(Base1)/4;

 

                cout << "[" << s << "] Base2::_vptr->"<<endl;

                pFun = (Fun)pVtab[s][0];

                cout << "     [0] "; pFun();

 

                Fun = (Fun)pVtab[s][1];

                cout << "     [1] "; pFun();

 

                pFun = (Fun)pVtab[s][2];

                cout << "     [2] "; pFun();

 

                pFun = (Fun)pVtab[s][3];

                out << "     [3] ";

                cout<<pFun<<endl;

 

                cout << "["<< s+1 <<"] Base2.ibase2 = " << (int)pVtab[s+1] << endl;

 

                s = s + sizeof(Base2)/4;

 

                cout << "[" << s << "] Base3::_vptr->"<<endl;

                pFun = (Fun)pVtab[s][0];

                cout << "     [0] "; pFun();

 

                pFun = (Fun)pVtab[s][1];

                cout << "     [1] "; pFun();

 

                pFun = (Fun)pVtab[s][2];

                cout << "     [2] "; pFun();

 

                pFun = (Fun)pVtab[s][3];

                 cout << "     [3] ";

                cout<<pFun<<endl;

 

                s++;

                cout << "["<< s <<"] Base3.ibase3 = " << (int)pVtab[s] << endl;

                s++;

                cout << "["<< s <<"] Derive.iderive = " << (int)pVtab[s] << endl;

 

鍏惰繍琛岀粨鏋滃涓嬫墍紺猴細錛堝湪VC++ 2003鍜孏++ 3.4.4涓嬶級

 

[0] Base1::_vptr->

     [0] Derive::f()

     [1] Base1::g()

     [2] Base1::h()

     [3] Driver::g1()

     [4] 00000000      ç 娉ㄦ剰錛氬湪GCC涓嬶紝榪欓噷鏄?

[1] Base1.ibase1 = 10

[2] Base2::_vptr->

     [0] Derive::f()

     [1] Base2::g()

     [2] Base2::h()

     [3] 00000000      ç 娉ㄦ剰錛氬湪GCC涓嬶紝榪欓噷鏄?

[3] Base2.ibase2 = 20

[4] Base3::_vptr->

     [0] Derive::f()

     [1] Base3::g()

     [2] Base3::h()

     [3] 00000000

[5] Base3.ibase3 = 30

[6] Derive.iderive = 100
 


浣跨敤鍥劇墖琛ㄧず鏄笅闈㈣繖涓牱瀛愶細

 


 

鎴戜滑鍙互鐪嬪埌錛?/p>

1錛?nbsp; 姣忎釜鐖剁被閮芥湁鑷繁鐨勮櫄琛ㄣ?/p>

2錛?nbsp; 瀛愮被鐨勬垚鍛樺嚱鏁拌鏀懼埌浜嗙涓涓埗綾葷殑琛ㄤ腑銆?/p>

3錛?nbsp; 鍐呭瓨甯冨眬涓紝鍏剁埗綾誨竷灞渚濇鎸夊0鏄庨『搴忔帓鍒椼?/p>

4錛?nbsp; 姣忎釜鐖剁被鐨勮櫄琛ㄤ腑鐨刦()鍑芥暟閮借overwrite鎴愪簡瀛愮被鐨刦()銆傝繖鏍峰仛灝辨槸涓轟簡瑙e喅涓嶅悓鐨勭埗綾葷被鍨嬬殑鎸囬拡鎸囧悜鍚屼竴涓瓙綾誨疄渚嬶紝鑰岃兘澶熻皟鐢ㄥ埌瀹為檯鐨勫嚱鏁般?/p>

 

鏈枃鏉ヨ嚜CSDN鍗氬錛岃漿杞借鏍囨槑鍑哄錛?a >http://blog.csdn.net/haoel/archive/2008/10/15/3081328.aspx



Sandy 2009-07-03 17:20 鍙戣〃璇勮
]]>
杞?C++ 浠g爜鎶宸澶存枃浠朵緷璧栵紝Pimpl娉?/title><link>http://www.shnenglu.com/SpringSnow/articles/80111.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Thu, 16 Apr 2009 02:11:00 GMT</pubDate><guid>http://www.shnenglu.com/SpringSnow/articles/80111.html</guid><wfw:comment>http://www.shnenglu.com/SpringSnow/comments/80111.html</wfw:comment><comments>http://www.shnenglu.com/SpringSnow/articles/80111.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/SpringSnow/comments/commentRss/80111.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/SpringSnow/services/trackbacks/80111.html</trackback:ping><description><![CDATA[浠婂ぉ鍦ㄩ欏電湅鍒扮殑,鎰熻涓嶉敊,鎽樿繃鏉ヤ繚瀛樹竴涓?<a href="http://www.shnenglu.com/CornerZhang/archive/2009/04/13/79004.html"><br>http://www.shnenglu.com/CornerZhang/archive/2009/04/13/79004.html</a><br>鍐呭濡備笅:<br><br> 澶存枃浠朵緷璧栵紝Pimpl娉曪紝鍔犻熺紪璇?br>   涓句釜渚嬪瓙:<br>      // File: SoundSystem.h<br><br>      #include "StreamFilter.h"<br>      #include "Emitters."<br><br>      <a title=class href="http://www.shnenglu.com/CornerZhang"><font color=#8d8c8c>class</font></a> SoundSystem {<br>      public:<br>         // ...<br>      private:<br>         StreamFilter currentFilter;<br>         EmitModeConfig modeConfig;<br>      };<br>   涓鐩簡鐒剁殑鏄紝鐪嬪緱鍑篠oundSystem瀹炵幇浣跨敤浜哠treamFilter鍜孍mitModeConfig鐨勫畾涔夛紝鎵浠?include 浜嗕粬浠殑瀹氫箟鍦ㄦSoundSystem.h涓紝鍙槸闅忕潃欏圭洰鐨勪笉鏂帹榪涳紝class SoundSystem涓緷璧栫殑浣跨敤綾誨瀷浼氬澶氾紝瀹冪殑header琚紩鍏ュ埌鍏跺畠妯″潡涓紝涓嶇煡涓嶈鐨勭紪璇戞椂闂磋秺鏉ヨ秺闀匡紝鏀硅繘涔嬶細<br>      // File: SoundSystem.h<br><br>      <a title=class href="http://www.shnenglu.com/CornerZhang"><font color=#8d8c8c>class</font></a> StreamFilter;<br>      <a title=class href="http://www.shnenglu.com/CornerZhang"><font color=#8d8c8c>class</font></a> EmitModeConfig;<br><br>      <a title=class href="http://www.shnenglu.com/CornerZhang"><font color=#8d8c8c>class</font></a> SoundSystem {<br>      public:<br>         // ...<br>      private:<br>         StreamFilter* currentFilterPtr;<br>         EmitModeConfig* modeConfigPtr;<br>      };<br><br>      // File: SoundSystem.cpp<br>      #include "StreamFilter.h"<br>      #include "Emitters."<br><br>      SoundSystem::SoundSystem() {<br>         //...<br>         currentFilterPtr = new StreamFilter;<br>         modeConfigPtr = new EmitModeConfig;<br>      }<br><br>      SoundSystem::~SoundSystem() {<br>         delete currentFilterPtr;<br>         delete modeConfigPtr;<br>         //...<br>      }<br>      榪欎箞涓鏉ワ紝鎶奡treamFilter鍜孍mitModeConfig鐨?include钘忓埌浜哠oundSystem鐨勫疄鐜頒唬鐮佷腑錛屼互鍚庡SoundSystem鐨勯儴鍒嗘敼鍔ㄤ笉浼氬鑷村叾瀹冩ā鍧楃殑rebuild鍝︼紝涓嶈繃鐢辨鍙兘浼氱壓鐗蹭竴鐐規晥鐜囧惂! <p>      璁板緱錛屾湁浣嶅井杞殑C++緲樻浜虹墿錛孒erb Sutter緇欒繖縐嶆妧宸хО涓篜impl ( Private Implemention ), 鐢ㄧ殑鎭板埌濂藉鏃訛紝鍙互鎻愰珮欏圭洰寮鍙戦熷害錛屽悓鏃舵ā鍧楃殑澶存枃浠墮棿鐨?include鍏崇郴寰椾互緙撹В錛屽彲浠ラ伩寮寰幆渚濊禆錛岃屼笖鍙互鑾峰緱涓涓壇濂界殑鐗╃悊璁捐銆?br><br>鎬葷粨:<br>      Pimpl鏂規硶鎰熻寰堜笉閿?<br>      浣跨敤榪欎釜鏂規硶鐨勬椂鍊?涓瀹氳娉ㄦ剰鐨勬槸鍦ㄨ繖涓湴鏂圭殑鍙樺寲,榪欎釜鏄垜絎簩閬嶇湅鐨勬椂鍊欐墠娉ㄦ剰鍒扮殑.<br>     <a title=class href="http://www.shnenglu.com/CornerZhang"><font color=#8d8c8c>class</font></a> SoundSystem {<br>      public:<br>         // ...<br>      private:<br>         <span style="COLOR: red">StreamFilter currentFilter;<br>         EmitModeConfig modeConfig;</span><br>      };<br><br>      閲囩敤Pimpl鏂規硶鍚?鍙樹負<br>     <a title=class href="http://www.shnenglu.com/CornerZhang"><font color=#8d8c8c>class</font></a> SoundSystem {<br>      public:<br>         // ...<br>      private:<br><span style="COLOR: red">         StreamFilter* currentFilterPtr;<br>         EmitModeConfig* modeConfigPtr;</span><br>      };<br>      鎵浠ュ湪.cpp鏂囦歡涓氨鏈変簡new鍜宒elete鐨勬搷浣?<br><br>      瀵逛簬榪欑鏂規硶鏈変竴涓枒闂?瀵逛簬閭g瀛樺湪鍖呭惈浼楀綾葷殑鎯呭喌涓?榪欑鏂規硶鐨勯┚椹笉鏄竴鑸漢鑳藉鎺屾彙鐨勫惂.鎴栬榪欑鏂規硶灝變笉澶嬌鐢ㄤ簡,涓嶅絳夊緟涓浼?緙栬瘧.<br><br><br></p> <img src ="http://www.shnenglu.com/SpringSnow/aggbug/80111.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/SpringSnow/" target="_blank">Sandy</a> 2009-04-16 10:11 <a href="http://www.shnenglu.com/SpringSnow/articles/80111.html#Feedback" target="_blank" style="text-decoration:none;">鍙戣〃璇勮</a></div>]]></description></item><item><title>杞?榪涚▼鐨勪簰鏂ヨ繍琛?/title><link>http://www.shnenglu.com/SpringSnow/articles/70466.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Fri, 26 Dec 2008 10:46:00 GMT</pubDate><guid>http://www.shnenglu.com/SpringSnow/articles/70466.html</guid><wfw:comment>http://www.shnenglu.com/SpringSnow/comments/70466.html</wfw:comment><comments>http://www.shnenglu.com/SpringSnow/articles/70466.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/SpringSnow/comments/commentRss/70466.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/SpringSnow/services/trackbacks/70466.html</trackback:ping><description><![CDATA[<strong>榪涚▼鐨勪簰鏂ヨ繍琛?br><a >http://bbs.onlycpp.net/viewthread.php?tid=540&extra=page%3D1</a><br><br></strong>銆銆姝e父鎯呭喌涓嬶紝涓涓繘紼嬬殑榪愯涓鑸槸涓嶄細褰卞搷鍒板叾浠栨鍦ㄨ繍琛岀殑榪涚▼鐨勩備絾鏄浜庢煇浜涙湁鐗規畩瑕佹眰鐨勫浠ョ嫭鍗犳柟寮忎嬌鐢ㄤ覆琛屽彛絳夌‖浠惰澶囩殑<span id="hvzpftn" class=t_tag onclick=tagshow(event) href="tag.php?name=%B3%CC%D0%F2">紼嬪簭</span>灝辮姹傚湪鍏惰繘紼嬭繍琛屾湡闂翠笉鍏佽鍏朵粬璇曞浘浣跨敤姝ょ鍙h澶囩殑紼嬪簭榪愯鐨勶紝鑰屼笖姝ょ被紼嬪簭閫氬父涔熶笉鍏佽榪愯鍚屼竴涓▼搴忕殑澶氫釜瀹炰緥銆傝繖灝卞紩鍑轟簡榪涚▼浜掓枼鐨勯棶棰樸?br><br>銆銆瀹炵幇榪涚▼浜掓枼鐨勬牳蹇冩濇兂姣旇緝綆鍗曪細榪涚▼鍦ㄥ惎鍔ㄦ椂棣栧厛媯鏌ュ綋鍓嶇郴緇熸槸鍚﹀凡緇忓瓨鍦ㄦ湁姝よ繘紼嬬殑瀹炰緥錛屽鏋滄病鏈夛紝榪涚▼灝嗘垚鍔熷垱寤哄茍璁劇疆鏍囪瘑瀹炰緥宸茬粡瀛樺湪鐨勬爣璁般傛鍚庡啀鍒涘緩榪涚▼鏃跺皢浼氶氳繃璇ユ爣璁拌岀煡鏅撳叾瀹炰緥宸茬粡瀛樺湪錛屼粠鑰屼繚璇佽繘紼嬪湪緋葷粺涓彧鑳藉瓨鍦ㄤ竴涓疄渚嬨傚叿浣撳彲浠ラ噰鍙?span class=t_tag onclick=tagshow(event) href="tag.php?name=%C4%DA%B4%E6">鍐呭瓨</span>鏄犲皠<span id="hvzpftn" class=t_tag onclick=tagshow(event) href="tag.php?name=%CE%C4%BC%FE">鏂囦歡</span>銆佹湁鍚嶄簨浠墮噺銆佹湁鍚嶄簰鏂ラ噺浠ュ強鍏ㄥ眬鍏變韓鍙橀噺絳夊縐嶆柟娉曟潵瀹炵幇銆備笅闈㈠氨鍒嗗埆瀵瑰叾涓叿鏈変唬琛ㄦх殑鏈夊悕浜掓枼閲忓拰鍏ㄥ眬鍏變韓鍙橀噺榪欎袱縐嶆柟娉曡繘琛屼粙緇嶏細<br> <table class=t_table style="WIDTH: 95%" cellSpacing=0 bgColor=#333333> <tbody> <tr bgColor=#ffffff> <td><font face="Fixedsys ">// 鍒涘緩浜掓枼閲?br>HANDLE m_hMutex = CreateMutex(NULL, FALSE, "Sample07");<br>// 媯鏌ラ敊璇唬鐮?br>if (GetLastError() == ERROR_ALREADY_EXISTS) {<br>銆// 濡傛灉宸叉湁浜掓枼閲忓瓨鍦ㄥ垯閲婃斁<span id="hvzpftn" class=t_tag onclick=tagshow(event) href="tag.php?name=%BE%E4%B1%FA">鍙ユ焺</span>騫跺浣嶄簰鏂ラ噺<br>銆CloseHandle(m_hMutex);<br>銆m_hMutex = NULL;<br>銆// 紼嬪簭閫鍑?br>銆return FALSE;<br>}</font></td> </tr> </tbody> </table> <br>銆銆涓婇潰榪欐浠g爜婕旂ず浜嗘湁鍚嶄簰鏂ラ噺鍦ㄨ繘紼嬩簰鏂ヤ腑鐨?span class=t_tag onclick=tagshow(event) href="tag.php?name=%D3%C3%B7%A8">鐢ㄦ硶</span>銆備唬鐮佺殑鏍稿績鏄疌reateMutex錛堬級瀵規湁鍚嶄簰鏂ラ噺鐨勫垱寤恒侰reateMutex錛堬級<span id="hvzpftn" class=t_tag onclick=tagshow(event) href="tag.php?name=%BA%AF%CA%FD">鍑芥暟</span>鍙敤鏉ュ垱寤轟竴涓湁鍚嶆垨鏃犲悕鐨勪簰鏂ラ噺瀵硅薄錛屽叾鍑芥暟鍘熷瀷涓猴細<br> <table class=t_table style="WIDTH: 95%" cellSpacing=0 bgColor=#333333> <tbody> <tr bgColor=#ffffff> <td><font face="Fixedsys ">HANDLE CreateMutex(<br>銆LPSECURITY_ATTRIBUTES lpMutexAttributes, // 鎸囧悜瀹夊叏灞炴х殑<span id="hvzpftn" class=t_tag onclick=tagshow(event) href="tag.php?name=%D6%B8%D5%EB">鎸囬拡</span><br>銆BOOL bInitialOwner, // 鍒濆鍖栦簰鏂ュ璞$殑鎵鏈夎?br>銆LPCTSTR lpName // 鎸囧悜浜掓枼瀵硅薄鍚嶇殑鎸囬拡<br>);</font></td> </tr> </tbody> </table> <br>銆銆濡傛灉鍑芥暟鎴愬姛鎵ц錛屽皢榪斿洖涓涓簰鏂ラ噺瀵硅薄鐨勫彞鏌勩傚鏋滃湪CreateMutex錛堬級鎵ц鍓嶅凡緇忓瓨鍦ㄦ湁鐩稿悓鍚嶅瓧鐨勪簰鏂ラ噺錛屽嚱鏁板皢榪斿洖榪欎釜宸茬粡瀛樺湪浜掓枼閲忕殑鍙ユ焺錛屽茍涓斿彲浠ラ氳繃GetLastError錛堬級寰楀埌閿欒浠g爜ERROR_ALREADY_EXIST銆傚彲瑙侊紝閫氳繃瀵歸敊璇唬鐮丒RROR_ALREADY_EXIST鐨勬嫻嬪彲浠ュ疄鐜癈reateMutex錛堬級瀵硅繘紼嬬殑浜掓枼銆?br>        寤虹珛浜掓枼浣擄紝鐢ㄦ潵鍚屾銆傚鏋滀竴涓嚎紼?span class=t_tag onclick=tagshow(event) href="tag.php?name=%BB%F1%C8%A1">鑾峰彇</span>浜嗕簰鏂ヤ綋錛屽垯瑕佽幏鍙栬浜掓枼浣撶殑絎簩涓嚎紼嬪皢琚寕璧鳳紝鐩村埌絎竴涓嚎紼嬮噴鏀捐浜掓枼浣撱?<br><br>鍙傛暟 <br>lpMutexAttributes <br>鎸囧悜涓涓猄ECURITY_ATTRIBUTES緇撴瀯鐨勬寚閽堬紝榪欎釜緇撴瀯鍐沖畾浜掓枼浣撳彞鏌勬槸鍚﹁瀛愯繘紼?span class=t_tag onclick=tagshow(event) href="tag.php?name=%BC%CC%B3%D0">緇ф壙</span>銆?nbsp;    <br>bInitialOwner <br>甯冨皵<span id="hvzpftn" class=t_tag onclick=tagshow(event) href="tag.php?name=%C0%E0%D0%CD">綾誨瀷</span>錛屽喅瀹氫簰鏂ヤ綋鐨勫垱寤鴻呮槸鍚︿負鎷ユ湁鑰?<br>lpName <br>鎸囧悜浜掓枼浣撳悕瀛?span class=t_tag onclick=tagshow(event) href="tag.php?name=%D7%D6%B7%FB">瀛楃</span>涓茬殑鎸囬拡銆備簰鏂ヤ綋鍙互鏈夊悕瀛椼?<br>浜掓枼浣撶殑濂藉鏄彲浠ュ湪榪涚▼闂村叡浜?br><strong>蹇冨緱浣撲細錛?br></strong><font face="Fixedsys ">    CreateMutex() </font><font face="Arial ">鐢ㄤ簬鏈夌嫭鍗犺姹傜殑紼嬪簭 (鍦ㄥ叾榪涚▼榪愯鏈熼棿涓嶅厑璁稿叾浠栦嬌鐢ㄦ绔彛璁懼鐨勭▼搴忚繍琛岋紝鎴栦笉鍏佽鍚屽悕紼嬪簭榪愯)銆傚鏈夊悓鍚嶇▼搴忚繍琛岋紝鍒欓氳繃 <strong>GetLastError錛堬級</strong>寰楀埌閿欒浠g爜 <strong>ERROR_ALREADY_EXIST</strong>銆?br><br>鍒氭墠鍙堟墽琛屼簡涓嬪緱鍑虹殑緇撴灉錛堢▼搴忓悕samp錛?br>       涓鑸儏鍐典笅錛氫竴榪涘叆璋冭瘯闃舵錛岃繘紼嬬鐞嗗櫒涓氨鍑虹幇浜唖amp榪涚▼錛屾墽琛屽埌<font face="Fixedsys "><font face="Arial ">CreateMutex鏃惰繑鍥炶繘紼嬪彞鏌勶紝鎵ц鍒癷f(GetLastError() == ERROR_ALREADY_EXISTS ) 榪涜鍒ゆ柇鏃訛紝璺寵繃涓嶆墽琛宨f涓殑鍐呭錛屾墍浠ヨ〃紺烘病鏈変簰鏂ャ?br>       璋冭瘯涔嬪墠鍏堣繍琛宒ebug涓殑samp.exe鍐嶈皟璇曪細涓榪涘叆璋冭瘯闃舵錛岃繘紼嬬鐞嗗櫒涓氨鍑虹幇浜嗕袱涓猻amp榪涚▼錛屾墽琛屽埌CreateMutex鏃惰繑鍥炶繘紼嬪彞鏌勶紝鎵ц鍒癷f(GetLastError() == ERROR_ALREADY_EXISTS ) 榪涜鍒ゆ柇鏃訛紝鎵цif涓殑鍐呭錛岃〃紺烘湁浜掓枼銆?/font></font></font> <img src ="http://www.shnenglu.com/SpringSnow/aggbug/70466.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/SpringSnow/" target="_blank">Sandy</a> 2008-12-26 18:46 <a href="http://www.shnenglu.com/SpringSnow/articles/70466.html#Feedback" target="_blank" style="text-decoration:none;">鍙戣〃璇勮</a></div>]]></description></item><item><title>杞? c++ noteshttp://www.shnenglu.com/SpringSnow/articles/70378.htmlSandySandyFri, 26 Dec 2008 01:15:00 GMThttp://www.shnenglu.com/SpringSnow/articles/70378.htmlhttp://www.shnenglu.com/SpringSnow/comments/70378.htmlhttp://www.shnenglu.com/SpringSnow/articles/70378.html#Feedback0http://www.shnenglu.com/SpringSnow/comments/commentRss/70378.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/70378.htmlhttp://www.shnenglu.com/mymsdn/archive/2008/12/25/cpp-notes-3.html
21銆乿ector鐨勫姩鎬佸闀夸紭浜庨鍏堝垎閰嶅唴瀛樸?/p>

浣跨敤vector鐨勬椂鍊欐渶濂藉姩鎬佸湴娣誨姞鍏冪礌銆傚畠涓嶅悓浜嶤鍜孞ava鎴栧叾浠栬璦鐨勬暟鎹被鍨嬶紝涓轟簡杈懼埌榪炵畫鎬э紝鏇存湁鏁堢殑鏂規硶鏄厛鍒濆鍖栦竴涓┖vector瀵硅薄錛岀劧鍚庡啀鍔ㄦ佹坊鍔犲厓绱狅紝鑰屼笉鏄鍏堝垎閰嶅唴瀛樸?/p>

22銆乿ector鍊煎垵濮嬪寲

鍐呯疆->0

鏈夐粯璁ゆ瀯閫?>璋冪敤榛樿鏋勯?/p>

鏃犻粯璁ゆ瀯閫狅紝鏈夊叾浠栨瀯閫?>紼嬪簭鍛樻墜鍔ㄦ彁渚涘垵濮嬪?/p>

鏃犻粯璁ゆ瀯閫狅紝涔熸棤鍏朵粬鏋勯?>鏍囧噯搴撲駭鐢熶竴涓甫鍒濆肩殑瀵硅薄

23銆佹暟緇勪笅鏍囩殑綾誨瀷

C++涓紝鏁扮粍涓嬫爣鐨勬紜被鍨嬫槸size_t鑰屼笉鏄痠nt錛宻ize_t鏄竴涓笌鏈哄櫒鐩稿叧鐨剈nsigned綾誨瀷銆?/p>

24銆佸湪澹版槑鎸囬拡鐨勬椂鍊欙紝鍙互鐢ㄧ┖鏍煎皢絎﹀彿*涓庡叾鍚庣殑鏍囪瘑絎﹀垎闅斿紑鏉ワ紝string *ps涓巗tring* ps閮芥槸鍙互鐨勶紝浣嗗悗鑰呭鏄撲駭鐢熻瑙o紝濡傦細

string* ps1,ps2;     //ps1鏄寚閽堬紝鑰宲s2鏄竴涓猻tring瀵硅薄

涔熷氨鏄錛屼漢浠彲鑳借鎶妔tring鍜宻tring*褰撲綔涓や釜綾誨瀷錛屾垨鑰呰string*琚綋浣滀竴縐嶆柊綾誨瀷鏉ョ湅寰咃紝浣嗚繖鏄敊鐨?/u>錛?/p>

25銆佷竴涓湁鏁堢殑鎸囬拡蹇呯劧鏄互涓嬩笁縐嶇姸鎬佷箣涓錛?/p>

  1. 淇濆瓨鐗瑰畾鐨勫璞$殑鍦板潃錛?
  2. 鎸囧悜鏌愪釜瀵硅薄鍚庨潰鐨勫彟涓瀵硅薄錛?
  3. 鎴栬呮槸0鍊箋傝〃鏄庡畠涓嶆寚鍚戜換浣曞璞°?/li>

鍏朵腑int *pi=0;涓巌nt *pi;鏄笉鍚岀殑銆傚墠鑰呮槸鍒濆鍖栨寚閽堟寚鍚?鍦板潃鐨勫璞★紙鍗充負NULL錛夛紙pi initialized to address to no object錛夛紝鍚庤呭嵈鏄湭鍒濆鍖栫殑錛坥k, but dangerous, pi is uninitialized錛夈?/p>

緙栬瘧鍣ㄥ彲浠ユ嫻嬪嚭0鍊肩殑鎸囬拡錛岀▼搴忓彲鍒ゆ柇璇ユ寚閽堝茍鏈寚鍚戜竴涓璞★紝鑰屾湭鍒濆鍖栫殑鎸囬拡鐨勪嬌鐢ㄦ爣鍑嗗茍鏈畾涔夛紝瀵瑰ぇ澶氭暟緙栬瘧鍣ㄦ潵璇達紝濡傛灉浣跨敤鏈垵濮嬪寲鐨勬寚閽堜細灝嗘寚閽堜腑瀛樻斁鐨勪笉紜畾鍊艱涓哄湴鍧錛岀劧鍚庢搷綰佃鍐呭瓨鍦板潃涓瓨鏀劇殑浣嶅唴瀹癸紝浣跨敤鏈垵濮嬪寲鐨勬寚閽堢浉褰撲簬鎿嶇旱榪欎釜涓嶇‘瀹氱殑鍦板潃涓瓨鍌ㄧ殑鍩虹鏁版嵁錛屽洜姝ゅ鏈垵濮嬪寲鐨勬寚閽堣繘琛岃В寮曠敤鏃訛紝閫氬父浼氬鑷寸▼搴忓穿婧冦?/p>

26銆乿oid*鎸囬拡

void*鎸囬拡鍙敮鎸佸嚑縐嶆湁闄愮殑鎿嶄綔錛?/p>

  1. 涓庡彟涓涓寚閽堣繘琛屾瘮杈冿紱
  2. 鍚戝嚱鏁頒紶閫抳oid*鎸囬拡鎴栦粠鍑芥暟榪斿洖void*鎸囬拡錛?
  3. 緇欏彟涓涓獀oid*鎸囬拡璧嬪箋?/li>

涓嶅厑璁鎬嬌鐢╲oid*鎸囬拡鎿嶇旱瀹冩墍鎸囧悜鐨勫璞°?/p>

27銆佹寚閽堝拰寮曠敤鐨勬瘮杈冿紙P105錛?/p>

铏界劧浣跨敤寮曠敤錛坮eference錛夊拰鎸囬拡閮藉彲闂存帴璁塊棶鍙︿竴涓鹼紝浣嗗畠浠箣闂存湁涓や釜閲嶈鍖哄埆銆傜涓涓尯鍒湪浜庡紩鐢ㄦ繪槸鎸囧悜鏌愪釜瀵硅薄錛氬畾涔夊紩鐢ㄦ椂娌℃湁鍒濆鍖栨槸閿欒鐨勩傜浜屼釜閲嶈鍖哄埆鍒欐槸璧嬪艱涓虹殑宸紓錛氱粰寮曠敤璧嬪間慨鏀圭殑鏄寮曠敤鎵鍏寵仈鐨勫璞$殑鍊鹼紝鑰屽茍涓嶆槸浣垮紩鐢ㄤ笌鍙︿竴涓璞″叧鑱斻傚紩鐢ㄤ竴緇忓垵濮嬪寲錛屽氨濮嬬粓鎸囧悜鍚屼竴涓壒瀹氬璞★紙榪欏氨鏄負浠涔堝紩鐢ㄥ繀欏誨湪瀹氫箟鏃跺垵濮嬪寲鐨勫師鍥狅級銆?/p>

28銆佹寚閽堜笌typedef錛圥112錛?/p>

const鏀懼湪綾誨瀷鍓嶅拰鏀懼湪綾誨瀷鍚庨兘鍙互琛ㄧず鍚屾牱鐨勬剰鎬濓細

const string s1;
string const s2;

s1鍜宻2鍧囪〃紺哄父閲忓瓧絎︿覆瀵硅薄銆?/p>

浣嗗洜姝ゅ氨瀵艱嚧浜嗕笅闈㈢殑鍙ュ瓙鍙兘浜х敓璇В錛?/p>

typedef string *pstring;
const pstring cstr;

瀹規槗閿欐妸typedef褰撴垚鏂囨湰鎵╁睍鑰屼駭鐢熶笅闈㈢殑鐞嗚В錛?/p>

const string *cstr; //榪欏茍闈炰笂闈緥瀛愮殑姝g‘鎰忔濓紒錛堥敊璇級

搴旇浠庡0鏄庣殑鍙ュ瓙鐪嬶紝涔熷氨鏄鍙湅const pstring cstr;錛屽湪榪欓噷pstring鏄竴縐嶆寚閽堢被鍨嬶紝const淇グ鐨勬槸榪欎釜綾誨瀷錛屽洜姝ゆ紜殑鐞嗚В搴旇鏄細

string *const cstr;

鑰宑onst pstring cstr;鍏跺疄鍙互琛ㄧず涓簆string const cstr;錛岃繖鏍風殑鍐欐硶鍒欎笉瀹規槗浜х敓璇В銆備粠鍙沖悜宸﹂槄璇葷殑鎰忔濆氨鏄細cstr鏄痗onst pstring綾誨瀷錛屽嵆鎸囧悜string瀵硅薄鐨刢onst鎸囬拡銆?/p>

29銆佸垱寤哄姩鎬佹暟緇勶紙娉ㄦ剰鐐硅浠g爜娉ㄩ噴錛?/p>

const char *cp1 = "some value";
char *cp2 = "other value";
int *piArray1 = new int[10];    //鍐呯疆綾誨瀷娌℃湁鍒濆鍖?
int *piArray2 = new int[10]();    //鍐呯疆綾誨瀷闇瑕佸姞絀哄渾鎷彿錛屽鏁扮粍鍏冪礌榪涜鍒濆鍖?
std::string *psArray1 = new std::string[10];    //榛樿鏋勯犲嚱鏁板垵濮嬪寲
std::cout<<"----------"<<std::endl
<<"*cp1\t\t:"<<*cp1<<std::endl
<<"*cp2\t\t:"<<*cp2<<std::endl
<<"*piArray1\t:"<<*piArray1<<std::endl
<<"*piArray2\t:"<<*piArray2<<std::endl
<<"*psArray1\t:"<<*psArray1<<std::endl
<<"----------"<<std::endl;

浣嗘槸涓嬮潰鐨勭粨鏋滃嵈涓庢蹇典笂鐨勪笉鍚岋細

////Visual Studio & MS VC++
//----------
//*cp1            :s
//*cp2            :o
//*piArray1       :-842150451
//*piArray2       :0
//*psArray1       :
//----------
////Eclipse&G++
//----------
//*cp1        :s
//*cp2        :o
//*piArray1    :4064608
//*piArray2    :4064560
//*psArray1    :
//----------

鐪嬫潵涓嶅悓鐨勭紪璇戝櫒瀵規鐨勫畾涔夎繕鏄湁鎵涓嶅悓錛屾敞鎰忕湅*piArray2鐨勫鹼紝鎸夌収璇存槑搴旇鏄垵濮嬪寲涓?錛屼絾榪欓噷鍗翠粛鐒惰〃鐜板嚭涓?piArray1涓鏍風殑鍊鹼紝璇存槑騫舵病鏈夊彂鐢熷垵濮嬪寲銆?/p>

瀵逛簬鍔ㄦ佸垎閰嶇殑鏁扮粍錛屽叾鍏冪礌鍙兘鍒濆鍖栦負鍏冪礌綾誨瀷鐨勯粯璁ゅ鹼紝鑰屼笉鑳藉儚鏁扮粍鍙橀噺涓鏍鳳紝鐢ㄥ垵濮嬪寲鍒楄〃涓烘暟緇勫厓绱犳彁渚涘悇涓嶇浉鍚岀殑鍒濆箋?/p>

30銆乧onst瀵硅薄鐨勫姩鎬佹暟緇?/p>

//P118
//error:uninitialized const array
const int *pciArray1 = new const int[10];
//ok:value-initialized const array
const int *pciArray2 = new const int[10]();
std::cout<<*pciArray1<<std::endl;
std::cout<<*pciArray2<<std::endl;

涓婇潰鐨勭ず渚嬬殑娉ㄩ噴鏉ヨ嚜涔︿腑錛屼絾鍦╒C++緙栬瘧鍣ㄥ拰G++緙栬瘧鍣ㄤ笅鍗翠笉鍚岋紝鍏蜂綋琛ㄧ幇涓猴細

  • VC++錛氱紪璇戞紜紝絎竴鍙ヨ緭鍑洪殢鏈哄湴鍧鐨勫鹼紝絎簩鍙ヨ緭鍑哄垵濮嬪寲鐨?錛堝叾涓寜鐓?#8220;鏍囧噯”絎竴縐嶅洜涓烘湭鍚慶onst鍙橀噺鍒濆鍖栵紝搴旇鏃犳硶閫氳繃緙栬瘧錛屼絾榪欓噷鍙互錛?
  • G++錛氱紪璇戦敊璇紝絎竴鍙ョ殑閿欒淇℃伅涓?#8220;uninitialized const in `new' of `const int'”錛屼絾絎簩鍙ユ寜鐓ф爣鍑嗗簲璇ヨ緭鍑?鐨勶紝榪欓噷鍗磋緭鍑轟簡闅忔満鍦板潃鐨勫箋?/li>

鐪嬫潵涓や釜緙栬瘧鍣ㄥ榪欎竴闂鐨勭湅娉曚笉澶竴鑷淬?/p>

Sandy 2008-12-26 09:15 鍙戣〃璇勮
]]>
杞?浣跨敤__FILE__鍜宊_LINE__瀹氫綅閿欒 http://www.shnenglu.com/SpringSnow/articles/70318.htmlSandySandyThu, 25 Dec 2008 05:04:00 GMThttp://www.shnenglu.com/SpringSnow/articles/70318.htmlhttp://www.shnenglu.com/SpringSnow/comments/70318.htmlhttp://www.shnenglu.com/SpringSnow/articles/70318.html#Feedback0http://www.shnenglu.com/SpringSnow/comments/commentRss/70318.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/70318.html浣跨敤__FILE__鍜宊_LINE__瀹氫綅閿欒
杞嚜:http://www.shnenglu.com/heath/archive/2008/12/25/58046.html#70307 [鍓嶈█錛氫嬌鐢╛_FILE__鍜宊_LINE__鏉ュ畾浣嶉敊璇凡緇忓薄瑙佷笉椴滐紝鐒惰屽叾涓竴浜涢亾鐞嗗張鏈夊嚑涓漢浠旂粏鎺㈢┒榪囥傛湰鏂囧弬鑰冧簡Curtis Krauskopf鐨勪竴綃囧悕涓?a target=_blank>Using __FILE__ and __LINE__ to Report Errors鐨勬枃绔狅紝甯屾湜杈懼埌瑙f儜涔嬫晥銆俔

闂錛氬綋榪愯鏃墮敊璇駭鐢熸椂錛屾垜鎬庢牱鎵嶈兘寰楀埌鍖呭惈C++鏂囦歡鍚嶅拰琛屽彿鐨勫瓧絎︿覆淇℃伅錛?br>鍥炵瓟錛氬湪C++涓殑__FILE__棰勭紪璇戞寚紺哄櫒鍖呭惈浜嗚緙栬瘧鐨勬枃浠跺悕錛岃宊_LINE__鍒欏寘鍚簡婧愪唬鐮佺殑琛屽彿銆俖_FILE__鍜宊_LINE__鐨勫墠鍚庨兘鍖呭惈浜?span style="COLOR: red">涓や釜涓嬪垝綰匡紝璁╂垜浠粩緇嗙湅鐪媉_FILE__鎵鍖呭惈鐨勬瘡涓瓧絎︼細

_ _ F I L E _ _

涓嬮潰灞曠ず浜嗗湪鎺у埗鍙扮▼搴忎腑濡傛灉鏄劇ず鏂囦歡鍚嶅拰浠g爜琛屽彿銆?br>

#include <stdio.h>

int main(int , char**)
{
     printf(
"This fake error is in %s on line %d\n",         __FILE__, __LINE__);
     
return 0;
}


杈撳嚭緇撴灉錛?br>
This fake error is in c:\temp\test.cpp on line 5

璁╂垜浠洿涓婁竴灞傛ゼ

鎴戞兂閫氳繃涓涓氱敤鍑芥暟error()鏉ユ姤鍛婇敊璇紝浠ヤ嬌褰撴煇涓敊璇彂鐢熸椂鎴戣兘璁劇疆鏂偣浠ュ強闅旂閿欒澶勭悊錛堜緥濡傦紝鍦ㄥ睆騫曚笂鎵撳嵃閿欒淇℃伅鎴栬呭啓鍏ユ棩蹇楋級銆傚洜姝わ紝鍑芥暟鐨勫師鍨嬪簲璇ユ槸榪欐牱鐨勫惂錛?br>

void error(const char *file, const unsigned long line, const char *msg); 

璋冪敤鏂瑰紡濡備笅錛?br>
error(__FILE__, __LINE__, "my error message");

棰勫鐞嗛瓟娉?br>

榪欓噷鏈変笁涓棶棰橀渶瑕佽В鍐籌細

  1. __FILE__鍜宊_LINE__鍦ㄦ瘡嬈¤皟鐢╡rror鏃朵綔涓哄弬鏁頒紶鍏ャ?/span>
  2. __FILE鍜宊_LINE__鍓嶅悗鐨勪笅鍒掔嚎寰堝鏄撹閬楀繕錛屼粠鑰屽鑷寸紪璇戦敊璇?/span>
  3. __LINE__鏄竴涓暣鏁幫紝榪欐棤鐤戝鍔犱簡error鍑芥暟鐨勫鏉傚害銆傛垜緇濅笉鎯崇洿鎺ヤ嬌鐢ㄦ暣鍨嬬殑__LINE__錛岃岄氬父閮芥槸灝嗚漿鎹負瀛楃涓叉墦鍗板埌灞忓箷鎴栧啓鍏ユ棩蹇楁枃浠躲?br>

__FILE__鍜宊_LINE__搴旇琚嚜鍔ㄥ鐞嗭紝鑰岄潪姣忔浣滀負鍙傛暟浼犻掔粰error錛岃繖鏍蜂細璁〆rror鐨勪嬌鐢ㄨ呮劅瑙夋洿鐖戒簺錛屽畠鐨勫艦寮忓彲鑳芥槸涓嬮潰榪欐牱錛?br>

error(AT, "my error message");

 
鎴戝笇鏈涗笂闈㈢殑瀹廇T灞曞紑涓猴細"c:\temp\test.cpp:5"銆傝屾柊鐨別rror鍑芥暟鍒欏彉鎴愶細

void error(const char *location, const char *msg);

 

鍥犱負Borland C++ Builder緙栬瘧鍣ㄨ兘澶熻嚜鍔ㄥ悎騫剁浉閭葷殑瀛楃涓詫紝鍥犳鎴戞妸AT鍐欐垚涓嬮潰榪欐牱錛?br>

#define AT __FILE__ ":" __LINE__ 


鐒惰屽畠鍗寸艦宸ヤ簡錛屽洜涓篲_LINE__琚墿灞曟垚浜嗘暣鏁拌岄潪瀛楃涓詫紝鎵浠ュ畯灞曞紑鍚庡彉鎴愶細

"c:\temp\test.cpp" ":"
5

榪欐槸涓涓棤鏁堢殑瀛楃涓詫紝鍥犱負鏈熬鏈変竴涓湭琚弻寮曞彿鍖呭惈鐨勬暣鏁般?

鎬庝箞鍔烇紵鍒潃鎬ワ紝涓涓壒孌婄殑棰勭紪璇戞寚紺哄櫒“#”鑳藉甯垜浠皢涓涓彉閲忚漿鎹㈡垚瀛楃涓層傛墍浠ラ噸鏂板畾涔夊畯錛?

#define AT __FILE__ ":" #__LINE__
鍢垮樋錛岃繖鏍鋒昏浜嗗惂銆傚埆楂樺叴寰楀お鏃╋紝榪欐牱涔熸槸涓嶈鐨勩傚洜涓虹紪璇戝櫒浼氭姳鎬?鏄釜鏃犳晥瀛楃銆傚叾瀹烇紝闂鏄?棰勭紪璇戞寚紺哄櫒鍙湁榪欐牱浣跨敤鎵嶄細
琚紜瘑鍒細
#define symbol(X) #X 

鍥犳錛屾垜鎶婁唬鐮佹敼涓猴細

#define STRINGIFY(x) #x
#define AT __FILE__ ":" STRINGIFY(__LINE__) 

鐒惰岋紝濂囨殑緇撴灉浜х敓浜嗭紝__LINE__灞呯劧琚綔涓轟簡杈撳嚭鐨勪竴閮ㄥ垎錛?br>
c:\temp\test.cpp:__LINE__: fake error

瑙e喅鏂規硶鏄啀鐢ㄤ竴涓畯鏉ュ寘瑁匰TRINGIFY()錛?br>

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)

OK錛屾垜浠敤涓嬮潰鐨勪唬鐮佹潵璇曡瘯錛?br>
#include <stdio.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
void error(const char *location, const char *msg)
{
  printf(
"Error at %s: %s\n", location, msg);
}
int main(int , char**)
{
  error(AT, 
"fake error");
  
return 0;
}


杈撳嚭緇撴灉錛?br>
Error at c:\temp\test\test.cpp:11: fake error

Visual Studio涓嬬殑瀹炶返
鍦ㄣ奧indows鏍稿績緙栫▼銆嬩腑錛孞effrey Richter鎻愪緵浜嗕笅闈㈢殑瀹忓湪緙栬瘧鏈熻緭鍑烘湁鐢ㄤ俊鎭細

#define chSTR2(x) #x
#define chSTR(x)  chSTR2(x)
#define chMSG(desc) message(__FILE__ "(" chSTR(__LINE__) "):" #desc)

message鏄竴涓緙栬瘧鎸囦護錛屼笂闈㈠畯鐨勪嬌鐢ㄦ柟娉曟槸錛?br>
#pragma chMSG(Fix this later)

緇撹
  1. 棰勭紪璇戞寚紺哄櫒__FILE__鍜宊_LINE__鑳藉鎻愪緵鏈夌敤鐨勪俊鎭?/span>
  2. __LINE__鐨勫鐞嗘柟寮忚繙姣旀垜浠兂璞$殑瑕佸鏉傘?/span>
  3. __FILE__琚鐞嗘垚瀛楃涓詫紝緇欐垜浠甫鏉ヤ簡涓嶅皯鏂逛究銆?


Sandy 2008-12-25 13:04 鍙戣〃璇勮
]]>
杞? fopen鎵撳紑鏂囦歡鏂瑰紡 http://www.shnenglu.com/SpringSnow/articles/70317.htmlSandySandyThu, 25 Dec 2008 04:59:00 GMThttp://www.shnenglu.com/SpringSnow/articles/70317.htmlhttp://www.shnenglu.com/SpringSnow/comments/70317.htmlhttp://www.shnenglu.com/SpringSnow/articles/70317.html#Feedback0http://www.shnenglu.com/SpringSnow/comments/commentRss/70317.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/70317.htmlfopen鎵撳紑鏂囦歡鏂瑰紡

http://www.shnenglu.com/iuranus/archive/2008/12/25/70315.html

     鏈榪戝啓涓涓枃浠舵搷浣滅被錛宖open鐨勫弬鏁扮潃瀹炶鎴戞悶浜嗗崐澶╋紝鍥犱負浠ュ墠灝辨槸鍥哄畾鐨勬柟寮忚鍐欐枃浠剁殑錛岀幇鍦ㄨ鍋氱伒媧諱簡錛屾墍浠ュ氨鏈変簺鍙傛暟鐞嗚В涓嶅鍑嗙‘銆備互涓嬫槸鍏充簬mode鍙傛暟鐨勫畾涔夈?br>
'r' 鍙鏂瑰紡鎵撳紑錛屽皢鏂囦歡鎸囬拡鎸囧悜鏂囦歡澶達紝濡傛灉鏂囦歡涓嶅瓨鍦紝鍒橣ile榪斿洖絀恒?br>'r+' 璇誨啓鏂瑰紡鎵撳紑錛屽皢鏂囦歡鎸囬拡鎸囧悜鏂囦歡澶達紝濡傛灉鏂囦歡涓嶅瓨鍦紝鍒橣ile榪斿洖絀恒?
'w' 鍐欏叆鏂瑰紡鎵撳紑錛屽皢鏂囦歡鎸囬拡鎸囧悜鏂囦歡澶村茍灝嗘枃浠跺ぇ灝忔埅涓洪浂銆傚鏋滄枃浠朵笉瀛樺湪鍒欏皾璇曞垱寤轟箣銆?
'w+' 璇誨啓鏂瑰紡鎵撳紑錛屽皢鏂囦歡鎸囬拡鎸囧悜鏂囦歡澶村茍灝嗘枃浠跺ぇ灝忔埅涓洪浂銆傚鏋滄枃浠朵笉瀛樺湪鍒欏皾璇曞垱寤轟箣銆?
'a' 鍐欏叆鏂瑰紡鎵撳紑錛屽皢鏂囦歡鎸囬拡鎸囧悜鏂囦歡鏈熬銆傚鏋滄枃浠朵笉瀛樺湪鍒欏皾璇曞垱寤轟箣銆?
'a+' 璇誨啓鏂瑰紡鎵撳紑錛屽皢鏂囦歡鎸囬拡鎸囧悜鏂囦歡鏈熬銆傚鏋滄枃浠朵笉瀛樺湪鍒欏皾璇曞垱寤轟箣銆?
'x' 鍒涘緩騫朵互鍐欏叆鏂瑰紡鎵撳紑錛屽皢鏂囦歡鎸囬拡鎸囧悜鏂囦歡澶淬傚鏋滄枃浠跺凡瀛樺湪錛屽垯 fopen() 璋冪敤澶辮觸騫惰繑鍥?FALSE銆?
'x' 鍒涘緩騫朵互鍐欏叆鏂瑰紡鎵撳紑錛屽皢鏂囦歡鎸囬拡鎸囧悜鏂囦歡澶淬傚鏋滄枃浠跺凡瀛樺湪錛屽垯 fopen() 璋冪敤澶辮觸騫惰繑鍥?FALSE銆?br>'b' 浣跨敤瀛楃b浣滀負鏂囦歡綾誨瀷鐨勫垽鏂紝鏄惁鏄痓inary鏂囦歡銆?br>
榪樻湁鍦ㄨ鏂囦歡鏃舵渶濂藉厛鍒ゆ柇涓嬭鏂囦歡鏄惁瀛樺湪
bool ClassA::IsFileExisted(const char* filePath)
{
   struct stat info;
   if(stat(filePath, &info) != 0)
   {
      return false;
   }
   else
      return true;
}


Sandy 2008-12-25 12:59 鍙戣〃璇勮
]]>
C++綾誨瀷杞崲絎︾殑浣跨敤 http://www.shnenglu.com/SpringSnow/articles/67376.htmlSandySandyThu, 20 Nov 2008 05:30:00 GMThttp://www.shnenglu.com/SpringSnow/articles/67376.htmlhttp://www.shnenglu.com/SpringSnow/comments/67376.htmlhttp://www.shnenglu.com/SpringSnow/articles/67376.html#Feedback0http://www.shnenglu.com/SpringSnow/comments/commentRss/67376.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/67376.htmlC++鐨勫洓涓被鍨嬭漿鎹㈣繍綆楃宸茬粡鏈夊緢涔呬簡,浣嗕竴鐩存病鏈夊紕娓呮瀹冧滑鐨勭敤娉?浠婂ぉ鐪嬪埌涓鏈功涓婄殑瑙i噴,鎵嶅ぇ鑷村湴鐨勪簡瑙d簡鍏跺叿浣撶殑鐢ㄦ硶.

鍏蜂綋褰掔撼濡備笅:

reinterpret_cast

璇ュ嚱鏁板皢涓涓被鍨嬬殑鎸囬拡杞崲涓哄彟涓涓被鍨嬬殑鎸囬拡.
榪欑杞崲涓嶇敤淇敼鎸囬拡鍙橀噺鍊煎瓨鏀炬牸寮?涓嶆敼鍙樻寚閽堝彉閲忓?,鍙渶鍦ㄧ紪璇戞椂閲嶆柊瑙i噴鎸囬拡鐨勭被鍨嬪氨鍙仛鍒?
reinterpret_cast 鍙互灝嗘寚閽堝艱漿鎹負涓涓暣鍨嬫暟,浣嗕笉鑳界敤浜庨潪鎸囬拡綾誨瀷鐨勮漿鎹?
渚?
//鍩烘湰綾誨瀷鎸囬拡鐨勭被鍨嬭漿鎹?br>double d=9.2;
double* pd = &d;
int *pi = reinterpret_cast<int*>(pd);  //鐩稿綋浜巌nt *pi = (int*)pd;

//涓嶇浉鍏崇殑綾葷殑鎸囬拡鐨勭被鍨嬭漿鎹?br>class A{};
class B{};
A* pa = new A;
B* pb = reinterpret_cast<B*>(pa);   //鐩稿綋浜嶣* pb = (B*)pa;

//鎸囬拡杞崲涓烘暣鏁?br>long l = reinterpret_cast<long>(pi);   //鐩稿綋浜巐ong l = (long)pi;


const_cast

璇ュ嚱鏁扮敤浜庡幓闄ゆ寚閽堝彉閲忕殑甯擱噺灞炴э紝灝嗗畠杞崲涓轟竴涓搴旀寚閽堢被鍨嬬殑鏅氬彉閲忋傚弽榪囨潵錛屼篃鍙互灝嗕竴涓潪甯擱噺鐨勬寚閽堝彉閲忚漿鎹負涓涓父鎸囬拡鍙橀噺銆?br>榪欑杞崲鏄湪緙栬瘧鏈熼棿鍋氬嚭鐨勭被鍨嬫洿鏀廣?br>渚嬶細
const int* pci = 0;
int* pk = const_cast<int*>(pci);  //鐩稿綋浜巌nt* pk = (int*)pci;

const A* pca = new A;
A* pa = const_cast<A*>(pca);     //鐩稿綋浜嶢* pa = (A*)pca;

鍑轟簬瀹夊叏鎬ц冭檻錛宑onst_cast鏃犳硶灝嗛潪鎸囬拡鐨勫父閲忚漿鎹負鏅氬彉閲忋?/p>


static_cast

璇ュ嚱鏁頒富瑕佺敤浜庡熀鏈被鍨嬩箣闂村拰鍏鋒湁緇ф壙鍏崇郴鐨勭被鍨嬩箣闂寸殑杞崲銆?br>榪欑杞崲涓鑸細鏇存敼鍙橀噺鐨勫唴閮ㄨ〃紺烘柟寮忥紝鍥犳錛宻tatic_cast搴旂敤浜庢寚閽堢被鍨嬭漿鎹㈡病鏈夊お澶ф剰涔夈?br>渚嬶細
//鍩烘湰綾誨瀷杞崲
int i=0;
double d = static_cast<double>(i);  //鐩稿綋浜?double d = (double)i;

//杞崲緇ф壙綾葷殑瀵硅薄涓哄熀綾誨璞?br>class Base{};
class Derived : public Base{};
Derived d;
Base b = static_cast<Base>(d);     //鐩稿綋浜?Base b = (Base)d;


dynamic_cast

瀹冧笌static_cast鐩稿錛屾槸鍔ㄦ佽漿鎹€?br>榪欑杞崲鏄湪榪愯鏃惰繘琛岃漿鎹㈠垎鏋愮殑錛屽茍闈炲湪緙栬瘧鏃惰繘琛岋紝鏄庢樉鍖哄埆浜庝笂闈笁涓被鍨嬭漿鎹㈡搷浣溿?br>璇ュ嚱鏁板彧鑳藉湪緇ф壙綾誨璞$殑鎸囬拡涔嬮棿鎴栧紩鐢ㄤ箣闂磋繘琛岀被鍨嬭漿鎹€傝繘琛岃漿鎹㈡椂錛屼細鏍規嵁褰撳墠榪愯鏃剁被鍨嬩俊鎭紝鍒ゆ柇綾誨瀷瀵硅薄涔嬮棿鐨勮漿鎹㈡槸鍚﹀悎娉曘俤ynamic_cast鐨勬寚閽堣漿鎹㈠け璐ワ紝鍙氳繃鏄惁涓簄ull媯嫻嬶紝寮曠敤杞崲澶辮觸鍒欐姏鍑轟竴涓猙ad_cast寮傚父銆?br>渚嬶細
class Base{};
class Derived : public Base{};

//媧劇敓綾繪寚閽堣漿鎹負鍩虹被鎸囬拡
Derived *pd = new Derived;
Base *pb = dynamic_cast<Base*>(pd);

if (!pb)
 cout << "綾誨瀷杞崲澶辮觸" << endl;

//娌℃湁緇ф壙鍏崇郴錛屼絾琚漿鎹㈢被鏈夎櫄鍑芥暟
class A(virtual ~A();)   //鏈夎櫄鍑芥暟
class B{}:
A* pa = new A;
B* pb  = dynamic_cast<B*>(pa);

濡傛灉瀵規棤緇ф壙鍏崇郴鎴栬呮病鏈夎櫄鍑芥暟鐨勫璞℃寚閽堣繘琛岃漿鎹€佸熀鏈被鍨嬫寚閽堣漿鎹互鍙婂熀綾繪寚閽堣漿鎹負媧劇敓綾繪寚閽堬紝閮戒笉鑳介氳繃緙栬瘧銆?/p>

Sandy 2008-11-20 13:30 鍙戣〃璇勮
]]>
杞細浣垮簲鐢ㄧ▼搴忓彧鑳借繍琛屼竴涓疄渚? http://www.shnenglu.com/SpringSnow/articles/65791.htmlSandySandySun, 02 Nov 2008 14:37:00 GMThttp://www.shnenglu.com/SpringSnow/articles/65791.htmlhttp://www.shnenglu.com/SpringSnow/comments/65791.htmlhttp://www.shnenglu.com/SpringSnow/articles/65791.html#Feedback3http://www.shnenglu.com/SpringSnow/comments/commentRss/65791.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/65791.htmlhttp://topic.csdn.net/t/20020917/11/1030014.html
浣垮簲鐢ㄧ▼搴忓彧鑳借繍琛屼竴涓疄渚? 
     
        Windows鏄榪涚▼鎿嶄綔緋葷粺錛屾鏋剁敓鎴愮殑搴旂敤紼嬪簭鍙互澶氭榪愯錛屽艦鎴愬涓繍琛屽疄渚嬨? 
  浣嗗湪鏈変簺鎯呭喌涓嬩負淇濊瘉搴旂敤紼嬪簭鐨勫畨鍏ㄨ繍琛岋紝瑕佹眰紼嬪簭鍙兘榪愯涓涓疄渚嬶紝姣斿紼?   
  搴忚浣跨敤鍙兘琚竴涓繘紼嬪崟鐙嬌鐢ㄧ殑鐗規畩紜歡錛堜緥濡傝皟鍒惰В璋冨櫒錛夋椂錛屽繀欏婚檺鍒剁▼    
  搴忓彧榪愯涓涓疄渚嬨? 
   
  榪欓噷娑夊強涓や釜鍩烘湰鐨勯棶棰橈紝涓鏄湪紼嬪簭鐨勭浜屼釜瀹炰緥鍚姩鏃訛紝濡備綍鍙戠幇璇ョ▼搴忓凡鏈?   
  涓涓疄渚嬪湪榪愯錛岃屾槸濡備綍灝嗙涓涓疄渚嬫縺媧伙紝鑰岀浜屼釜瀹炰緥閫鍑恒? 
   
  瀵逛簬絎竴涓棶棰橈紝鍙互閫氳繃緇欏簲鐢ㄧ▼搴忚緗俊鍙烽噺錛屽疄渚嬪惎鍔ㄦ椂棣栧厛媯嫻嬭淇″彿閲忥紝    
  濡傚凡瀛樺湪錛屽垯璇存槑紼嬪簭宸茶繍琛屼竴涓疄渚嬨? 
   
  絎簩涓棶棰樼殑闅劇偣鏄幏鍙栫涓涓疄渚嬬殑涓葷獥瀵硅薄鎸囬拡鎴栧彞鏌勶紝鐒跺悗渚垮彲鐢?   
  SetForegroundWindow鏉ユ縺媧匯傝櫧鐒禙indWindow鍑芥暟鑳藉鎵炬榪愯鐫鐨勭獥鍙o紝浣嗚鍑?   
  鏁拌姹傛寚鏄庢墍瀵繪壘紿楀彛鐨勬爣棰樻垨紿楀彛綾誨悕錛屼笉鏄疄鐜伴氱敤鏂規硶鐨勯斿緞銆? 
  鎴戜滑鍙互鐢╓in32   SDK鍑芥暟SetProp鏉ョ粰搴旂敤紼嬪簭涓葷獥璁劇疆涓涓壒鏈夌殑鏍囪銆? 
  鐢℅etDesktopWindow   鍙互鑾峰彇Windows緋葷粺涓繪帶紿楀彛瀵硅薄鎸囬拡鎴栧彞鏌勶紝鎵鏈夊簲鐢ㄧ▼  
  搴忎富紿楅兘鍙湅鎴愯紿楀彛鐨勫瓙紿楀彛錛屽嵆鍙敤GetWindow鍑芥暟鏉ヨ幏寰楀畠浠殑瀵硅薄鎸囬拡鎴栧彞  
  鏌勩傜敤Win32   SDK鍑芥暟GetProp鏌ユ壘姣忎竴搴旂敤紼嬪簭涓葷獥鏄惁鍖呭惈鏈夋垜浠緗殑鐗瑰畾鏍? 
  璁頒究鍙‘瀹氬畠鏄惁鎴戜滑瑕佸鎵劇殑絎竴涓疄渚嬩富紿椼備嬌絎簩涓疄渚嬮鍑哄緢綆鍗曪紝鍙  
  璁╁叾搴旂敤紼嬪簭瀵硅薄鐨処nitInstance鍑芥暟榪斿洖FALSE鍗沖彲銆傛澶栵紝褰撲富紿楀彛閫鍑烘椂錛屽簲  
  鐢≧emoveProp鍑芥暟鍒犻櫎鎴戜滑涓哄叾璁劇疆鐨勬爣璁般? 
   
  涓嬮潰鐨処nitInstance銆丱nCreate鍜孫nDestroy鍑芥暟浠g爜灝嗗疄鐜頒笂榪扮殑鎿嶄綔錛? 
   
  BOOL   CEllipseWndApp::InitInstance()    
  {    
  //   鐢ㄥ簲鐢ㄧ▼搴忓悕鍒涘緩淇″彿閲?   
  HANDLE   hSem   =   CreateSemaphore(NULL,   1,   1,   m_pszExeName);    
   
  //   淇″彿閲忓凡瀛樺湪錛?   
  //   淇″彿閲忓瓨鍦紝鍒欑▼搴忓凡鏈変竴涓疄渚嬭繍琛?   
  if   (GetLastError()   ==   ERROR_ALREADY_EXISTS)    
  {    
  //   鍏抽棴淇″彿閲忓彞鏌?   
  CloseHandle(hSem);    
  //   瀵繪壘鍏堝墠瀹炰緥鐨勪富紿楀彛    
  HWND   hWndPrevious   =   ::GetWindow(::GetDesktopWindow(),GW_CHILD);    
  while   (::IsWindow(hWndPrevious))    
  {    
  //   媯鏌ョ獥鍙f槸鍚︽湁棰勮鐨勬爣璁?    
  //   鏈夛紝鍒欐槸鎴戜滑瀵繪壘鐨勪富紿?   
  if   (::GetProp(hWndPrevious,   m_pszExeName))    
  {    
  //   涓葷獥鍙e凡鏈灝忓寲錛屽垯鎭㈠鍏跺ぇ灝?   
  if   (::IsIconic(hWndPrevious))    
  ::ShowWindow(hWndPrevious,SW_RESTORE);    
   
  //   灝嗕富紿楁縺媧?   
  ::SetForegroundWindow(hWndPrevious);    
   
  //   灝嗕富紿楃殑瀵硅瘽妗嗘縺媧?   
  ::SetForegroundWindow(    
  ::GetLastActivePopup(hWndPrevious));    
   
  //   閫鍑烘湰瀹炰緥    
  return   FALSE;    
  }    
  //   緇х畫瀵繪壘涓嬩竴涓獥鍙?   
  hWndPrevious   =   ::GetWindow(hWndPrevious,GW_HWNDNEXT);  
  }    
  //   鍓嶄竴瀹炰緥宸插瓨鍦紝浣嗘壘涓嶅埌鍏朵富紿?   
  //   鍙兘鍑洪敊浜?   
  //   閫鍑烘湰瀹炰緥    
  return   FALSE;    
  }    
  AfxEnableControlContainer();    
  //   Standard   initialization    
  //   If   you   are   not   using   these   features   and   wish   to   reduce   the   size    
  //   of   your   final   executable,   you   should   remove   from   the   following    
  //   the   specific   initialization   routines   you   do   not   need.    
  #ifdef   _AFXDLL    
  Enable3dControls();   //   Call   this   when   using   MFC   in   a   shared   DLL    
  #else    
  Enable3dControlsStatic();//   Call   this   when   linking   to   MFC   statically    
  #endif    
   
  CEllipseWndDlg   dlg;    
  m_pMainWnd   =   &dlg;    
  int   nResponse   =   dlg.DoModal();    
  if   (nResponse   ==   IDOK)    
  {    
  //   TODO:   Place   code   here   to   handle   when   the   dialog   is    
  //   dismissed   with   OK    
  }    
  else   if   (nResponse   ==   IDCANCEL)    
  {    
  //   TODO:   Place   code   here   to   handle   when   the   dialog   is    
  //   dismissed   with   Cancel    
  }    
  //   Since   the   dialog   has   been   closed,   return   FALSE   so   that   we   exit   the    
  //   application,   rather   than   start   the   application's   message   pump.    
  return   FALSE;    
  }    
   
  int   CEllipseWndDlg::OnCreate(LPCREATESTRUCT   lpCreateStruct)      
  {    
  if   (CDialog::OnCreate(lpCreateStruct)   ==   -1)    
  return   -1;    
  //   璁劇疆瀵繪壘鏍囪    
  ::SetProp(m_hWnd,   AfxGetApp()->m_pszExeName,   (HANDLE)1);    
  return   0;    
  }    
   
  void   CEllipseWndDlg::OnDestroy()      
  {    
  CDialog::OnDestroy();    
  //   鍒犻櫎瀵繪壘鏍囪    
  ::RemoveProp(m_hWnd,   AfxGetApp()->m_pszExeName);      
  }  
           
   
  瀵逛互涓婁唬鐮佺殑琛ュ厖錛?   
                  鏌ョ湅浠g爜鍜孷C鐨勫府鍔╁悗錛屽彂鐜伴棶棰樺湪浜庡師鏂囧湪鍒涘緩淇″彿閲忓拰璁劇疆瀵繪壘鏍囪鏃朵嬌鐢? 
  鐨勬槸   CWinApp   鐨勬垚鍛樺彉閲?  m_pszExeName錛岃鎴愬憳鍙橀噺鍏跺疄鏄簲鐢ㄧ▼搴忔墽琛屾枃浠剁殑鍚? 
  縐板幓鎺夋墿灞曞悕鍚庣殑閮ㄥ垎錛岃屼笉鏄簲鐢ㄧ▼搴忓悕銆?   
   
  鐪熸鐨勫簲鐢ㄧ▼搴忓悕搴斾負鎴愬憳鍙橀噺   m_pszAppName,    
  浜庢槸灝嗙敤鍒癿_pszExeName鐨勪笁澶勪唬鐮佸潎鏀逛負m_pszAppName錛岄噸鏂扮紪璇戞墽琛岋紝鎯呭喌娑堝け銆?   
   
  鏈鍚庡啀鎻愪緵涓涓柟娉曞拰涓涓俊鎭細    
   
          鍙︿竴縐嶄嬌搴旂敤紼嬪簭鍙兘榪愯涓涓疄渚嬬殑鏂規硶錛屽彧闇鍦↖nitInstance()鐨勬渶寮濮嬫坊  
  鍔犱笅鍒楄鍙ュ嵆鍙細    
  HANDLE   m_hMutex=CreateMutex(NULL,TRUE,   m_pszAppName);    
  if(GetLastError()==ERROR_ALREADY_EXISTS)   {   return   FALSE;   }  
   
  浣嗚繖縐嶆柟娉曠殑涓嶈凍涔嬪鏄笉鑳藉皢宸茬粡鍚姩鐨勫疄渚嬫縺媧匯?   
   
                鍦╯tingray鍏徃鏁寸悊寮鍙戠殑MFCFAQ杞歡涓篃鎻愪緵浜嗕竴浜涙柟娉曘傝杞歡瀹為檯鏄竴涓? 
  MFC浣跨敤鎶宸х殑澶ф眹闆嗭紝瀵逛嬌鐢∕FC鏋佹湁甯姪錛屽悇浣嶆湅鍙嬩笉濡ㄥ幓stingray鍏徃鐨勪富欏典笅    
  杞姐?nbsp;    
   

Sandy 2008-11-02 22:37 鍙戣〃璇勮
]]>
杞細娣卞叆嫻呭嚭Win32澶氱嚎紼嬭璁′箣MFC鐨勫綰跨▼(浣滆咃細瀹嬪疂鍗?http://www.shnenglu.com/SpringSnow/articles/65790.htmlSandySandySun, 02 Nov 2008 14:36:00 GMThttp://www.shnenglu.com/SpringSnow/articles/65790.htmlhttp://www.shnenglu.com/SpringSnow/comments/65790.htmlhttp://www.shnenglu.com/SpringSnow/articles/65790.html#Feedback0http://www.shnenglu.com/SpringSnow/comments/commentRss/65790.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/65790.html杞嚜錛?a >http://blog.ednchina.com/hotpower/174823/message.aspx 

鏍囩錛?鏃犳爣絳?/p>

娣卞叆嫻呭嚭Win32澶氱嚎紼嬭璁′箣MFC鐨勫綰跨▼(浣滆咃細瀹嬪疂鍗?

1銆佸垱寤哄拰緇堟綰跨▼

銆銆鍦∕FC紼嬪簭涓垱寤轟竴涓嚎紼嬶紝瀹滆皟鐢ˋfxBeginThread鍑芥暟銆傝鍑芥暟鍥犲弬鏁頒笉鍚岃屽叿鏈変袱縐嶉噸杞界増鏈紝鍒嗗埆瀵瑰簲宸ヤ綔鑰呯嚎紼嬪拰鐢ㄦ埛鎺ュ彛錛圲I錛夌嚎紼嬨?br>
銆銆宸ヤ綔鑰呯嚎紼?br>
CWinThread *AfxBeginThread(
銆AFX_THREADPROC pfnThreadProc, //鎺у埗鍑芥暟
銆LPVOID pParam, //浼犻掔粰鎺у埗鍑芥暟鐨勫弬鏁?br>銆int nPriority = THREAD_PRIORITY_NORMAL, //綰跨▼鐨勪紭鍏堢駭
銆UINT nStackSize = 0, //綰跨▼鐨勫爢鏍堝ぇ灝?br>銆DWORD dwCreateFlags = 0, //綰跨▼鐨勫垱寤烘爣蹇?br>銆LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL //綰跨▼鐨?a class=bluekey target=_blank>瀹夊叏灞炴?br>);

銆銆宸ヤ綔鑰呯嚎紼嬬紪紼嬭緝涓虹畝鍗曪紝鍙渶緙栧啓綰跨▼鎺у埗鍑芥暟鍜屽惎鍔ㄧ嚎紼嬪嵆鍙備笅闈㈢殑浠g爜緇欏嚭浜嗗畾涔変竴涓帶鍒跺嚱鏁板拰鍚姩瀹冪殑榪囩▼錛?br>
//綰跨▼鎺у埗鍑芥暟
UINT MfcThreadProc(LPVOID lpParam)
{
銆CExampleClass *lpObject = (CExampleClass*)lpParam;
銆if (lpObject == NULL || !lpObject->IsKindof(RUNTIME_CLASS(CExampleClass)))
銆銆return - 1; //杈撳叆鍙傛暟闈炴硶
銆//綰跨▼鎴愬姛鍚姩
銆while (1)

銆return 0;
}

//鍦∕FC紼嬪簭涓惎鍔ㄧ嚎紼?br>AfxBeginThread(MfcThreadProc, lpObject);

銆銆UI綰跨▼

銆銆鍒涘緩鐢ㄦ埛鐣岄潰綰跨▼鏃訛紝蹇呴』棣栧厛浠嶤WinThread 媧劇敓綾伙紝騫朵嬌鐢?DECLARE_DYNCREATE 鍜?IMPLEMENT_DYNCREATE 瀹忓0鏄庢綾匯?br>
銆銆涓嬮潰緇欏嚭浜咰WinThread綾葷殑鍘熷瀷錛堟坊鍔犱簡鍏充簬鍏墮噸瑕佸嚱鏁板姛鑳藉拰鏄惁闇瑕佽緇ф壙綾婚噸杞界殑娉ㄩ噴錛夛細

class CWinThread : public CCmdTarget
{
銆DECLARE_DYNAMIC(CWinThread)

銆public:
銆銆// Constructors
銆銆CWinThread();
銆銆BOOL CreateThread(DWORD dwCreateFlags = 0, UINT nStackSize = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);

銆銆// Attributes
銆銆CWnd* m_pMainWnd; // main window (usually same AfxGetApp()->m_pMainWnd)
銆銆CWnd* m_pActiveWnd; // active main window (may not be m_pMainWnd)
銆銆BOOL m_bAutoDelete; // enables 'delete this' after thread termination

銆銆// only valid while running
銆銆HANDLE m_hThread; // this thread's HANDLE
銆銆operator HANDLE() const;
銆銆DWORD m_nThreadID; // this thread's ID

銆銆int GetThreadPriority();
銆銆BOOL SetThreadPriority(int nPriority);

銆銆// Operations
銆銆DWORD SuspendThread();
銆銆DWORD ResumeThread();
銆銆BOOL PostThreadMessage(UINT message, WPARAM wParam, LPARAM lParam);

銆銆// Overridables
銆銆//鎵ц綰跨▼瀹炰緥鍒濆鍖栵紝蹇呴』閲嶅啓
銆銆virtual BOOL InitInstance();

銆銆// running and idle processing
銆銆//鎺у埗綰跨▼鐨勫嚱鏁幫紝鍖呭惈娑堟伅娉碉紝涓鑸笉閲嶅啓
銆銆virtual int Run();

銆銆//娑堟伅璋冨害鍒癟ranslateMessage鍜孌ispatchMessage涔嬪墠瀵瑰叾榪涜絳涢夛紝
銆銆//閫氬父涓嶉噸鍐?br>銆銆virtual BOOL PreTranslateMessage(MSG* pMsg);

銆銆virtual BOOL PumpMessage(); // low level message pump

銆銆//鎵ц綰跨▼鐗瑰畾鐨勯棽緗椂闂村鐞嗭紝閫氬父涓嶉噸鍐?br>銆銆virtual BOOL OnIdle(LONG lCount); // return TRUE if more idle processing
銆銆virtual BOOL IsIdleMessage(MSG* pMsg); // checks for special messages

銆銆//綰跨▼緇堟鏃舵墽琛屾竻闄わ紝閫氬父闇瑕侀噸鍐?br>銆銆virtual int ExitInstance(); // default will 'delete this'

銆銆//鎴幏鐢辯嚎紼嬬殑娑堟伅鍜屽懡浠ゅ鐞嗙▼搴忓紩鍙戠殑鏈鐞嗗紓甯革紝閫氬父涓嶉噸鍐?br>銆銆virtual LRESULT ProcessWndProcException(CException* e, const MSG* pMsg);

銆銆// Advanced: handling messages sent to message filter hook
銆銆virtual BOOL ProcessMessageFilter(int code, LPMSG lpMsg);

銆銆// Advanced: virtual access to m_pMainWnd
銆銆virtual CWnd* GetMainWnd();

銆銆// Implementation
銆public:
銆銆virtual ~CWinThread();
銆銆#ifdef _DEBUG
銆銆銆virtual void AssertValid() const;
銆銆銆virtual void Dump(CDumpContext& dc) const;
銆銆銆int m_nDisablePumpCount; // Diagnostic trap to detect illegal re-entrancy
銆銆#endif
銆銆void CommonConstruct();
銆銆virtual void Delete();
銆銆// 'delete this' only if m_bAutoDelete == TRUE

銆銆// message pump for Run
銆銆MSG m_msgCur; // current message

銆public:
銆銆// constructor used by implementation of AfxBeginThread
銆銆CWinThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam);

銆銆// valid after construction
銆銆LPVOID m_pThreadParams; // generic parameters passed to starting function
銆銆AFX_THREADPROC m_pfnThreadProc;

銆銆// set after OLE is initialized
銆銆void (AFXAPI* m_lpfnOleTermOrFreeLib)(BOOL, BOOL);
銆銆COleMessageFilter* m_pMessageFilter;

銆protected:
銆銆CPoint m_ptCursorLast; // last mouse position
銆銆UINT m_nMsgLast; // last mouse message
銆銆BOOL DispatchThreadMessageEx(MSG* msg); // helper
銆銆void DispatchThreadMessage(MSG* msg); // obsolete
};

銆銆鍚姩UI綰跨▼鐨凙fxBeginThread鍑芥暟鐨勫師鍨嬩負錛?br>
CWinThread *AfxBeginThread(
銆//浠嶤WinThread媧劇敓鐨勭被鐨?RUNTIME_CLASS
銆CRuntimeClass *pThreadClass,
銆int nPriority = THREAD_PRIORITY_NORMAL,
銆UINT nStackSize = 0,
銆DWORD dwCreateFlags = 0,
銆LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);

銆銆鎴戜滑鍙互鏂逛究鍦頒嬌鐢╒C++ 6.0綾誨悜瀵煎畾涔変竴涓戶鎵胯嚜CWinThread鐨勭敤鎴風嚎紼嬬被銆備笅闈㈢粰鍑轟駭鐢熸垜浠嚜瀹氫箟鐨凜WinThread瀛愮被CMyUIThread鐨勬柟娉曘?br>
銆銆鎵撳紑VC++ 6.0綾誨悜瀵鹼紝鍦ㄥ涓嬬獥鍙d腑閫夋嫨Base Class綾諱負CWinThread錛岃緭鍏ュ瓙綾誨悕涓篊MyUIThread錛岀偣鍑?OK"鎸夐挳鍚庡氨浜х敓浜嗙被CMyUIThread銆?br>

銆銆鍏舵簮浠g爜妗嗘灦涓猴細

/////////////////////////////////////////////////////////////////////////////
// CMyUIThread thread

class CMyUIThread : public CWinThread
{
銆DECLARE_DYNCREATE(CMyUIThread)
銆protected:
銆銆CMyUIThread(); // protected constructor used by dynamic creation

銆銆// Attributes
銆public:

銆銆// Operations
銆public:

銆銆// Overrides
銆銆// ClassWizard generated virtual function overrides
銆銆//{{AFX_VIRTUAL(CMyUIThread)
銆銆public:
銆銆銆virtual BOOL InitInstance();
銆銆銆virtual int ExitInstance();
銆銆//}}AFX_VIRTUAL

銆銆// Implementation
銆protected:
銆銆virtual ~CMyUIThread();

銆銆// Generated message map functions
銆銆//{{AFX_MSG(CMyUIThread)
銆銆銆// NOTE - the ClassWizard will add and remove member functions here.
銆銆//}}AFX_MSG

銆DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////
// CMyUIThread

IMPLEMENT_DYNCREATE(CMyUIThread, CWinThread)

CMyUIThread::CMyUIThread()
{}

CMyUIThread::~CMyUIThread()
{}

BOOL CMyUIThread::InitInstance()
{
銆// TODO: perform and per-thread initialization here
銆return TRUE;
}

int CMyUIThread::ExitInstance()
{
銆// TODO: perform any per-thread cleanup here
銆return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CMyUIThread, CWinThread)
//{{AFX_MSG_MAP(CMyUIThread)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

銆銆浣跨敤涓嬪垪浠g爜灝卞彲浠ュ惎鍔ㄨ繖涓猆I綰跨▼錛?br>
CMyUIThread *pThread;
pThread = (CMyUIThread*)
AfxBeginThread( RUNTIME_CLASS(CMyUIThread) );

銆銆鍙﹀錛屾垜浠篃鍙互涓嶇敤AfxBeginThread 鍒涘緩綰跨▼錛岃屾槸鍒嗗涓嬩袱姝ュ畬鎴愶細

銆銆錛?錛夎皟鐢ㄧ嚎紼嬬被鐨勬瀯閫犲嚱鏁板垱寤轟竴涓嚎紼嬪璞★紱

銆銆錛?錛夎皟鐢–WinThread::CreateThread鍑芥暟鏉ュ惎鍔ㄨ綰跨▼銆?br>
銆銆鍦ㄧ嚎紼嬭嚜韜唴璋冪敤AfxEndThread鍑芥暟鍙互緇堟璇ョ嚎紼嬶細

void AfxEndThread(
銆UINT nExitCode //the exit code of the thread
);


銆銆瀵逛簬UI綰跨▼鑰岃█錛屽鏋滄秷鎭槦鍒椾腑鏀懼叆浜哤M_QUIT娑堟伅錛屽皢緇撴潫綰跨▼銆?br>
銆銆鍏充簬UI綰跨▼鍜屽伐浣滆呯嚎紼嬬殑鍒嗛厤錛屾渶濂界殑鍋氭硶鏄細灝嗘墍鏈変笌UI鐩稿叧鐨勬搷浣滄斁鍏ヤ富綰跨▼錛屽叾瀹冪殑綰補鐨勮繍綆楀伐浣滀氦緇欑嫭绔嬬殑鏁頒釜宸ヤ綔鑰呯嚎紼嬨?br>
銆銆鍊欐嵎鍏堢敓鏃╀簺鏃墮棿鍠滄涓篗DI紼嬪簭鐨勬瘡涓獥鍙e垱寤轟竴涓嚎紼嬶紝浠栧悗鏉ユ緞娓呬簡榪欎釜閿欒銆傚洜涓哄鏋滀負MDI紼嬪簭鐨勬瘡涓獥鍙i兘鍗曠嫭鍒涘緩涓涓嚎紼嬶紝鍦ㄧ獥鍙h繘琛屽垏鎹㈢殑鏃跺欙紝灝嗚繘琛岀嚎紼嬬殑涓婁笅鏂囧垏鎹紒

2.綰跨▼闂撮氫俊

銆銆MFC涓畾涔変簡緇ф壙鑷狢SyncObject綾葷殑CCriticalSection 銆丆CEvent銆丆Mutex銆丆Semaphore綾誨皝瑁呭拰綆鍖栦簡WIN32 API鎵鎻愪緵鐨勪復鐣屽尯銆佷簨浠躲佷簰鏂ュ拰淇″彿閲忋備嬌鐢ㄨ繖浜涘悓姝ユ満鍒訛紝蹇呴』鍖呭惈"Afxmt.h"澶存枃浠躲備笅鍥劇粰鍑轟簡綾葷殑緇ф壙鍏崇郴錛?br>

銆銆浣滀負CSyncObject綾葷殑緇ф壙綾伙紝鎴戜滑浠呬粎浣跨敤鍩虹被CSyncObject鐨勬帴鍙e嚱鏁板氨鍙互鏂逛究銆佺粺涓鐨勬搷浣淐CriticalSection 銆丆CEvent銆丆Mutex銆丆Semaphore綾伙紝涓嬮潰鏄疌SyncObject綾葷殑鍘熷瀷錛?br>
class CSyncObject : public CObject
{
銆DECLARE_DYNAMIC(CSyncObject)

銆// Constructor
銆public:
銆銆CSyncObject(LPCTSTR pstrName);

銆銆// Attributes
銆public:
銆銆operator HANDLE() const;
銆銆HANDLE m_hObject;

銆銆// Operations
銆銆virtual BOOL Lock(DWORD dwTimeout = INFINITE);
銆銆virtual BOOL Unlock() = 0;
銆銆virtual BOOL Unlock(LONG /* lCount */, LPLONG /* lpPrevCount="NULL" */)
銆銆{ return TRUE; }

銆銆// Implementation
銆public:
銆銆virtual ~CSyncObject();
銆銆#ifdef _DEBUG
銆銆銆CString m_strName;
銆銆銆virtual void AssertValid() const;
銆銆銆virtual void Dump(CDumpContext& dc) const;
銆銆#endif
銆銆friend class CSingleLock;
銆銆friend class CMultiLock;
};

銆銆CSyncObject綾繪渶涓昏鐨勪袱涓嚱鏁版槸Lock鍜孶nlock錛岃嫢鎴戜滑鐩存帴浣跨敤CSyncObject綾誨強鍏舵淳鐢熺被錛屾垜浠渶瑕侀潪甯稿皬蹇冨湴鍦↙ock涔嬪悗璋冪敤Unlock銆?br>
銆銆MFC鎻愪緵鐨勫彟涓や釜綾籆SingleLock錛堢瓑寰呬竴涓璞★級鍜孋MultiLock錛堢瓑寰呭涓璞★級涓烘垜浠紪鍐欏簲鐢ㄧ▼搴忔彁渚涗簡鏇寸伒媧葷殑鏈哄埗錛屼笅闈互瀹為檯鏉ラ槓榪癈SingleLock鐨勭敤娉曪細

class CThreadSafeWnd

銆銆~CThreadSafeWnd(){}
銆銆void SetWindow(CWnd *pwnd)
銆銆{
銆銆銆m_pCWnd = pwnd;
銆銆}
銆銆void PaintBall(COLORREF color, CRect &rc);
銆private:
銆銆CWnd *m_pCWnd;
銆銆CCriticalSection m_CSect;
};

void CThreadSafeWnd::PaintBall(COLORREF color, CRect &rc)
{
銆CSingleLock csl(&m_CSect);
銆//緙虹渷鐨凾imeout鏄疘NFINITE錛屽彧鏈塵_Csect琚縺媧伙紝csl.Lock()鎵嶈兘榪斿洖
銆//true錛岃繖閲屼竴鐩寸瓑寰?br>銆if (csl.Lock())
;
銆{
銆銆// not necessary
銆銆//AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
銆銆CDC *pdc = m_pCWnd->GetDC();
銆銆CBrush brush(color);
銆銆CBrush *oldbrush = pdc->SelectObject(&brush);
銆銆pdc->Ellipse(rc);
銆銆pdc->SelectObject(oldbrush);
銆銆GdiFlush(); // don't wait to update the display
銆}
}

銆銆涓婅堪瀹炰緥璁茶堪浜嗙敤CSingleLock瀵筗indows GDI鐩稿叧瀵硅薄榪涜淇濇姢鐨勬柟娉曪紝涓嬮潰鍐嶇粰鍑轟竴涓叾浠栨柟闈㈢殑渚嬪瓙錛?br>
int array1[10], array2[10];
CMutexSection section; //鍒涘緩涓涓狢Mutex綾葷殑瀵硅薄

//璧嬪肩嚎紼嬫帶鍒跺嚱鏁?br>UINT EvaluateThread(LPVOID param)
{
銆CSingleLock singlelock;
銆singlelock(&section);

銆//浜掓枼鍖哄煙
銆singlelock.Lock();
銆for (int i = 0; i < 10; i++)
銆銆array1[i] = i;
銆singlelock.Unlock();
}
//鎷瘋礉綰跨▼鎺у埗鍑芥暟
UINT CopyThread(LPVOID param)
{
銆CSingleLock singlelock;
銆singlelock(&section);

銆//浜掓枼鍖哄煙
銆singlelock.Lock();
銆for (int i = 0; i < 10; i++)
銆銆array2[i] = array1[i];
銆singlelock.Unlock();
}
}

AfxBeginThread(EvaluateThread, NULL); //鍚姩璧嬪肩嚎紼?br>AfxBeginThread(CopyThread, NULL); //鍚姩鎷瘋礉綰跨▼

銆銆涓婇潰鐨勪緥瀛愪腑鍚姩浜嗕袱涓嚎紼婨valuateThread鍜孋opyThread錛岀嚎紼婨valuateThread鎶?0涓暟璧嬪肩粰鏁扮粍array1[]錛岀嚎紼婥opyThread灝嗘暟緇刟rray1[]鎷瘋礉緇欐暟緇刟rray2[]銆傜敱浜庢暟緇勭殑鎷瘋礉鍜岃祴鍊奸兘鏄暣浣撹涓猴紝濡傛灉涓嶄互浜掓枼褰㈠紡鎵ц浠g爜孌碉細

for (int i = 0; i < 10; i++)
array1[i] = i;

銆銆鍜?br>
for (int i = 0; i < 10; i++)
array2[i] = array1[i];

銆銆鍏剁粨鏋滄槸寰堥毦棰勬枡鐨勶紒

銆銆闄や簡鍙嬌鐢–CriticalSection銆丆Event銆丆Mutex銆丆Semaphore浣滀負綰跨▼闂村悓姝ラ氫俊鐨勬柟寮忎互澶栵紝鎴戜滑榪樺彲浠ュ埄鐢≒ostThreadMessage鍑芥暟鍦ㄧ嚎紼嬮棿鍙戦佹秷鎭細

BOOL PostThreadMessage(DWORD idThread, // thread identifier
UINT Msg, // message to post
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter

 

3.綰跨▼涓庢秷鎭槦鍒?br>
銆銆鍦╓IN32涓紝姣忎竴涓嚎紼嬮兘瀵瑰簲鐫涓涓秷鎭槦鍒椼傜敱浜庝竴涓嚎紼嬪彲浠ヤ駭鐢熸暟涓獥鍙o紝鎵浠ュ茍涓嶆槸姣忎釜紿楀彛閮藉搴旂潃涓涓秷鎭槦鍒椼備笅鍒楀嚑鍙ヨ瘽搴旇浣滀負"瀹氱悊"琚浣忥細

銆銆"瀹氱悊" 涓

銆銆鎵鏈変駭鐢熺粰鏌愪釜紿楀彛鐨勬秷鎭紝閮藉厛鐢卞垱寤鴻繖涓獥鍙g殑綰跨▼澶勭悊錛?br>
銆銆"瀹氱悊" 浜?br>
銆銆Windows灞忓箷涓婄殑姣忎竴涓帶浠墮兘鏄竴涓獥鍙o紝鏈夊搴旂殑紿楀彛鍑芥暟銆?br>
銆銆娑堟伅鐨勫彂閫侀氬父鏈変袱縐嶆柟寮忥紝涓鏄疭endMessage錛屼竴鏄疨ostMessage錛屽叾鍘熷瀷鍒嗗埆涓猴細

LRESULT SendMessage(HWND hWnd, // handle of destination window
銆UINT Msg, // message to send
銆WPARAM wParam, // first message parameter
銆LPARAM lParam // second message parameter
);
BOOL PostMessage(HWND hWnd, // handle of destination window
銆UINT Msg, // message to post
銆WPARAM wParam, // first message parameter
銆LPARAM lParam // second message parameter
);

銆銆涓や釜鍑芥暟鍘熷瀷涓殑鍥涗釜鍙傛暟鐨勬剰涔夌浉鍚岋紝浣嗘槸SendMessage鍜孭ostMessage鐨勮涓烘湁宸紓銆係endMessage蹇呴』絳夊緟娑堟伅琚鐞嗗悗鎵嶈繑鍥烇紝鑰孭ostMessage浠呬粎灝嗘秷鎭斁鍏ユ秷鎭槦鍒椼係endMessage鐨勭洰鏍囩獥鍙e鏋滃睘浜庡彟涓涓嚎紼嬶紝鍒欎細鍙戠敓綰跨▼涓婁笅鏂囧垏鎹紝絳夊緟鍙︿竴綰跨▼澶勭悊瀹屾垚娑堟伅銆備負浜嗛槻姝㈠彟涓綰跨▼褰撴帀錛屽鑷碨endMessage姘歌繙涓嶈兘榪斿洖錛屾垜浠彲浠ヨ皟鐢⊿endMessageTimeout鍑芥暟錛?br>
LRESULT SendMessageTimeout(
銆HWND hWnd, // handle of destination window
銆UINT Msg, // message to send
銆WPARAM wParam, // first message parameter
銆LPARAM lParam, // second message parameter
銆UINT fuFlags, // how to send the message
銆UINT uTimeout, // time-out duration
銆LPDWORD lpdwResult // return value for synchronous call
);

銆銆4. MFC綰跨▼銆佹秷鎭槦鍒椾笌MFC紼嬪簭鐨?鐢熸鍥犳灉"

銆銆鍒嗘瀽MFC紼嬪簭鐨勪富綰跨▼鍚姩鍙婃秷鎭槦鍒楀鐞嗙殑榪囩▼灝嗘湁鍔╀簬鎴戜滑榪涗竴姝ョ悊瑙I綰跨▼涓庢秷鎭槦鍒楃殑鍏崇郴錛屼負姝ゆ垜浠渶瑕佺畝鍗曞湴鍙欒堪涓涓婱FC紼嬪簭鐨?鐢熸鍥犳灉"錛堜警鎹鳳細銆婃繁鍏ユ祬鍑篗FC銆嬶級銆?br>
銆銆浣跨敤VC++ 6.0鐨勫悜瀵煎畬鎴愪竴涓渶綆鍗曠殑鍗曟枃妗f灦鏋凪FC搴旂敤紼嬪簭MFCThread錛?br>
銆銆錛?錛?杈撳叆MFC EXE宸ョ▼鍚峂FCThread錛?br>
銆銆錛?錛?閫夋嫨鍗曟枃妗f灦鏋勶紝涓嶆敮鎸丏ocument/View緇撴瀯錛?br>
銆銆錛?錛?ActiveX銆?D container絳夊叾浠栭夐」閮介夋嫨鏃犮?br>
銆銆鎴戜滑鏉ュ垎鏋愯繖涓伐紼嬨備笅闈㈡槸浜х敓鐨勬牳蹇冩簮浠g爜錛?br>
銆銆MFCThread.h 鏂囦歡

class CMFCThreadApp : public CWinApp
{
銆public:
銆銆CMFCThreadApp();

銆銆// Overrides
銆銆// ClassWizard generated virtual function overrides
銆銆//{{AFX_VIRTUAL(CMFCThreadApp)
銆銆銆public:
銆銆銆銆virtual BOOL InitInstance();
銆銆//}}AFX_VIRTUAL

銆銆// Implementation

銆public:
銆銆//{{AFX_MSG(CMFCThreadApp)
銆銆銆afx_msg void OnAppAbout();
銆銆銆// NOTE - the ClassWizard will add and remove member functions here.
銆銆銆// DO NOT EDIT what you see in these blocks of generated code !
銆銆//}}AFX_MSG
銆DECLARE_MESSAGE_MAP()
};

銆銆MFCThread.cpp鏂囦歡

CMFCThreadApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CMFCThreadApp initialization

BOOL CMFCThreadApp::InitInstance()
{
銆…
銆CMainFrame* pFrame = new CMainFrame;
銆m_pMainWnd = pFrame;

銆// create and load the frame with its resources
銆pFrame->LoadFrame(IDR_MAINFRAME,WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,NULL);
銆// The one and only window has been initialized, so show and update it.
銆pFrame->ShowWindow(SW_SHOW);
銆pFrame->UpdateWindow();

銆return TRUE;
}

銆銆MainFrm.h鏂囦歡

#include "ChildView.h"

class CMainFrame : public CFrameWnd
{
銆public:
銆銆CMainFrame();
銆protected:
銆銆DECLARE_DYNAMIC(CMainFrame)

銆銆// Attributes
銆public:

銆銆// Operations
銆public:
銆銆// Overrides
銆銆// ClassWizard generated virtual function overrides
銆銆//{{AFX_VIRTUAL(CMainFrame)
銆銆銆virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
銆銆銆virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
銆銆//}}AFX_VIRTUAL

銆銆// Implementation
銆public:
銆銆virtual ~CMainFrame();
銆銆#ifdef _DEBUG
銆銆銆virtual void AssertValid() const;
銆銆銆virtual void Dump(CDumpContext& dc) const;
銆銆#endif
銆銆CChildView m_wndView;

銆銆// Generated message map functions
銆protected:
銆//{{AFX_MSG(CMainFrame)
銆銆afx_msg void OnSetFocus(CWnd *pOldWnd);
銆銆// NOTE - the ClassWizard will add and remove member functions here.
銆銆// DO NOT EDIT what you see in these blocks of generated code!
銆//}}AFX_MSG
銆DECLARE_MESSAGE_MAP()
};

銆銆MainFrm.cpp鏂囦歡

IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
銆//{{AFX_MSG_MAP(CMainFrame)
銆銆// NOTE - the ClassWizard will add and remove mapping macros here.
銆銆// DO NOT EDIT what you see in these blocks of generated code !
銆銆ON_WM_SETFOCUS()
銆//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
銆// TODO: add member initialization code here
}

CMainFrame::~CMainFrame()
{}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
銆if( !CFrameWnd::PreCreateWindow(cs) )
銆銆return FALSE;
銆銆// TODO: Modify the Window class or styles here by modifying
銆銆// the CREATESTRUCT cs

銆cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
銆cs.lpszClass = AfxRegisterWndClass(0);
銆return TRUE;
}

銆銆ChildView.h鏂囦歡

// CChildView window

class CChildView : public CWnd
{
銆// Construction
銆public:
銆銆CChildView();

銆銆// Attributes
銆public:
銆銆// Operations
銆public:
銆銆// Overrides
銆銆// ClassWizard generated virtual function overrides
銆銆//{{AFX_VIRTUAL(CChildView)
銆銆銆protected:
銆銆銆銆virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
銆銆//}}AFX_VIRTUAL

銆銆// Implementation
銆public:
銆銆virtual ~CChildView();

銆銆// Generated message map functions
銆protected:
銆銆//{{AFX_MSG(CChildView)
銆銆銆afx_msg void OnPaint();
銆銆//}}AFX_MSG
銆DECLARE_MESSAGE_MAP()
};

ChildView.cpp鏂囦歡
// CChildView

CChildView::CChildView()
{}

CChildView::~CChildView()
{}

BEGIN_MESSAGE_MAP(CChildView,CWnd )
//}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChildView message handlers

BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
{
銆if (!CWnd::PreCreateWindow(cs))
銆銆return FALSE;

銆cs.dwExStyle |= WS_EX_CLIENTEDGE;
銆cs.style &= ~WS_BORDER;
銆cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,::LoadCursor(NULL, IDC_ARROW),
HBRUSH(COLOR_WINDOW+1),NULL);

銆return TRUE;
}

void CChildView::OnPaint()
{
銆CPaintDC dc(this); // device context for painting

銆// TODO: Add your message handler code here
銆// Do not call CWnd::OnPaint() for painting messages
}

銆銆鏂囦歡MFCThread.h鍜孧FCThread.cpp瀹氫箟鍜屽疄鐜扮殑綾籆MFCThreadApp緇ф壙鑷狢WinApp綾伙紝鑰孋WinApp綾誨張緇ф壙鑷狢WinThread綾伙紙CWinThread綾誨張緇ф壙鑷狢CmdTarget綾伙級錛屾墍浠MFCThread鏈川涓婃槸涓涓狹FC綰跨▼綾伙紝涓嬪浘緇欏嚭浜嗙浉鍏崇殑綾誨眰嬈$粨鏋勶細

 

鎴戜滑鎻愬彇CWinApp綾誨師鍨嬬殑涓閮ㄥ垎錛?br>
class CWinApp : public CWinThread
{
銆DECLARE_DYNAMIC(CWinApp)
銆public:
銆銆// Constructor
銆銆CWinApp(LPCTSTR lpszAppName = NULL);// default app name
銆銆// Attributes
銆銆// Startup args (do not change)
銆銆HINSTANCE m_hInstance;
銆銆HINSTANCE m_hPrevInstance;
銆銆LPTSTR m_lpCmdLine;
銆銆int m_nCmdShow;
銆銆// Running args (can be changed in InitInstance)
銆銆LPCTSTR m_pszAppName; // human readable name
銆銆LPCTSTR m_pszExeName; // executable name (no spaces)
銆銆LPCTSTR m_pszHelpFilePath; // default based on module path
銆銆LPCTSTR m_pszProfileName; // default based on app name

銆銆// Overridables
銆銆virtual BOOL InitApplication();
銆銆virtual BOOL InitInstance();
銆銆virtual int ExitInstance(); // return app exit code
銆銆virtual int Run();
銆銆virtual BOOL OnIdle(LONG lCount); // return TRUE if more idle processing
銆銆virtual LRESULT ProcessWndProcException(CException* e,const MSG* pMsg);

銆public:
銆銆virtual ~CWinApp();
銆protected:
銆銆DECLARE_MESSAGE_MAP()
};

銆銆SDK紼嬪簭鐨刉inMain 鎵瀹屾垚鐨勫伐浣滅幇鍦ㄧ敱CWinApp 鐨勪笁涓嚱鏁板畬鎴愶細

virtual BOOL InitApplication();
virtual BOOL InitInstance();
virtual int Run();

銆銆"CMFCThreadApp theApp;"璇彞瀹氫箟鐨勫叏灞鍙橀噺theApp鏄暣涓▼寮忕殑application object錛屾瘡涓涓狹FC 搴旂敤紼嬪簭閮芥湁涓涓傚綋鎴戜滑鎵цMFCThread紼嬪簭鐨勬椂鍊欙紝榪欎釜鍏ㄥ眬鍙橀噺琚瀯閫犮倀heApp 閰嶇疆瀹屾垚鍚庯紝WinMain寮濮嬫墽琛屻備絾鏄▼搴忎腑騫舵病鏈塛inMain鐨勪唬鐮侊紝瀹冨湪鍝噷鍛紵鍘熸潵MFC鏃╁凡鍑嗗濂藉茍鐢盠inker鐩存帴鍔犲埌搴旂敤紼嬪簭浠g爜涓殑錛屽叾鍘熷瀷涓猴紙瀛樺湪浜嶸C++6.0瀹夎鐩綍涓嬫彁渚涚殑APPMODUL.CPP鏂囦歡涓級錛?br>
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
銆// call shared/exported WinMain
銆return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}

銆銆鍏朵腑璋冪敤鐨凙fxWinMain濡備笅錛堝瓨鍦ㄤ簬VC++6.0瀹夎鐩綍涓嬫彁渚涚殑WINMAIN.CPP鏂囦歡涓級錛?br>
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
銆ASSERT(hPrevInstance == NULL);

銆int nReturnCode = -1;
銆CWinThread* pThread = AfxGetThread();
銆CWinApp* pApp = AfxGetApp();

銆// AFX internal initialization
銆if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
銆銆goto InitFailure;

銆// App global initializations (rare)
銆if (pApp != NULL && !pApp->InitApplication())
銆銆goto InitFailure;

銆// Perform specific initializations
銆if (!pThread->InitInstance())
銆{
銆銆if (pThread->m_pMainWnd != NULL)
銆銆{
銆銆銆TRACE0("Warning: Destroying non-NULL m_pMainWndn");
銆銆銆pThread->m_pMainWnd->DestroyWindow();
銆銆}
銆銆nReturnCode = pThread->ExitInstance();
銆銆goto InitFailure;
銆}
銆nReturnCode = pThread->Run();

銆InitFailure:
銆#ifdef _DEBUG
銆銆// Check for missing AfxLockTempMap calls
銆銆if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
銆銆{
銆銆銆TRACE1("Warning: Temp map lock count non-zero (%ld).n",
AfxGetModuleThreadState()->m_nTempMapLock);
銆銆}
銆銆AfxLockTempMaps();
銆銆AfxUnlockTempMaps(-1);
銆#endif

銆AfxWinTerm();
銆return nReturnCode;
}

銆銆鎴戜滑鎻愬彇涓誨共錛屽疄闄呬笂錛岃繖涓嚱鏁板仛鐨勪簨鎯呬富瑕佹槸錛?br>
CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp();
AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
pApp->InitApplication()
pThread->InitInstance()
pThread->Run();

銆銆鍏朵腑錛孖nitApplication 鏄敞鍐岀獥鍙g被鍒殑鍦烘墍錛汭nitInstance鏄駭鐢熺獥鍙e茍鏄劇ず紿楀彛鐨勫満鎵錛汻un鏄彁鍙栧茍鍒嗘淳娑堟伅鐨勫満鎵銆傝繖鏍鳳紝MFC灝卞悓WIN32 SDK紼嬪簭瀵瑰簲璧鋒潵浜嗐侰WinThread::Run鏄▼搴忕敓鍛界殑"媧繪按婧愬ご"錛堜警鎹鳳細銆婃繁鍏ユ祬鍑篗FC銆嬶紝鍑芥暟瀛樺湪浜嶸C++ 6.0瀹夎鐩綍涓嬫彁渚涚殑THRDCORE.CPP鏂囦歡涓級錛?br>
// main running routine until thread exits
int CWinThread::Run()
{
銆ASSERT_VALID(this);

銆// for tracking the idle time state
銆BOOL bIdle = TRUE;
銆LONG lIdleCount = 0;

銆// acquire and dispatch messages until a WM_QUIT message is received.
銆for (;;)
銆{
銆銆// phase1: check to see if we can do idle work
銆銆while (bIdle && !::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
銆銆{
銆銆銆// call OnIdle while in bIdle state
銆銆銆if (!OnIdle(lIdleCount++))
銆銆銆銆bIdle = FALSE; // assume "no idle" state
銆銆}

銆銆// phase2: pump messages while available
銆銆do
銆銆{
銆銆銆// pump message, but quit on WM_QUIT
銆銆銆if (!PumpMessage())
銆銆銆銆return ExitInstance();

銆銆銆// reset "no idle" state after pumping "normal" message
銆銆銆if (IsIdleMessage(&m_msgCur))
銆銆銆{
銆銆銆銆bIdle = TRUE;
銆銆銆銆lIdleCount = 0;
銆銆銆}

銆銆} while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
銆}
銆ASSERT(FALSE); // not reachable
}

銆銆鍏朵腑鐨凱umpMessage鍑芥暟鍙堝搴斾簬錛?br>
/////////////////////////////////////////////////////////////////////////////
// CWinThread implementation helpers

BOOL CWinThread::PumpMessage()
{
銆ASSERT_VALID(this);

銆if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))
銆{
銆銆return FALSE;
銆}

銆// process this message
銆if(m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur))

銆return TRUE;
}

銆銆鍥犳錛屽拷鐣DLE鐘舵侊紝鏁翠釜RUN鐨勬墽琛屾彁鍙栦富騫插氨鏄細

do while (::PeekMessage(...));

銆銆鐢辨錛屾垜浠緩绔嬩簡MFC娑堟伅鑾峰彇鍜屾淳鐢熸満鍒朵笌WIN32 SDK紼嬪簭涔嬮棿鐨勫搴斿叧緋匯備笅闈㈢戶緇垎鏋怣FC娑堟伅鐨?緇曡"榪囩▼銆?br>
銆銆鍦∕FC涓紝鍙鏄疌Wnd 琛嶇敓綾誨埆錛屽氨鍙互鎷︿笅浠諱綍Windows娑堟伅銆備笌紿楀彛鏃犲叧鐨凪FC綾誨埆錛堜緥濡侰Document 鍜孋WinApp錛夊鏋滀篃鎯沖鐞嗘秷鎭紝蹇呴』琛嶇敓鑷狢CmdTarget錛屽茍涓斿彧鍙兘鏀跺埌WM_COMMAND娑堟伅銆傛墍鏈夎兘榪涜MESSAGE_MAP鐨勭被閮界戶鎵胯嚜CCmdTarget錛屽錛?br>

銆銆MFC涓璏ESSAGE_MAP鐨勫畾涔変緷璧栦簬浠ヤ笅涓変釜瀹忥細

DECLARE_MESSAGE_MAP()

BEGIN_MESSAGE_MAP(
銆theClass, //Specifies the name of the class whose message map this is
銆baseClass //Specifies the name of the base class of theClass
)

END_MESSAGE_MAP()

銆銆鎴戜滑紼嬪簭涓秹鍙婂埌鐨勬湁錛歁FCThread.h銆丮ainFrm.h銆丆hildView.h鏂囦歡

DECLARE_MESSAGE_MAP()
MFCThread.cpp鏂囦歡
BEGIN_MESSAGE_MAP(CMFCThreadApp, CWinApp)
//{{AFX_MSG_MAP(CMFCThreadApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
MainFrm.cpp鏂囦歡
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code !
ON_WM_SETFOCUS()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
ChildView.cpp鏂囦歡
BEGIN_MESSAGE_MAP(CChildView,CWnd )
//}AFX_MSG_MAP
END_MESSAGE_MAP()

銆銆鐢辮繖浜涘畯錛孧FC寤虹珛浜嗕竴涓秷鎭槧灝勮〃錛堟秷鎭祦鍔ㄧ綉錛夛紝鎸夌収娑堟伅嫻佸姩緗戝尮閰嶅搴旂殑娑堟伅澶勭悊鍑芥暟錛屽畬鎴愭暣涓秷鎭殑"緇曡"銆?br>
銆銆鐪嬪埌榪欓噷鐩鎬俊浣犳湁榪欐牱鐨勭枒闂細紼嬪簭瀹氫箟浜咰WinApp綾葷殑theApp鍏ㄥ眬鍙橀噺錛屽彲鏄粠鏉ユ病鏈夎皟鐢ˋfxBeginThread鎴杢heApp.CreateThread鍚姩綰跨▼鍛錛宼heApp瀵瑰簲鐨勭嚎紼嬫槸鎬庝箞鍚姩鐨勶紵

銆銆絳旓細MFC鍦ㄨ繖閲岀敤浜嗗緢楂樻槑鐨勪竴鎷涖傚疄闄呬笂錛岀▼搴忓紑濮嬭繍琛岋紝絎竴涓嚎紼嬫槸鐢?a class=bluekey target=_blank>鎿嶄綔緋葷粺錛圤S錛夊惎鍔ㄧ殑錛屽湪CWinApp鐨勬瀯閫犲嚱鏁伴噷錛孧FC灝唗heApp"瀵瑰簲"鍚戜簡榪欎釜綰跨▼錛屽叿浣撶殑瀹炵幇鏄繖鏍風殑錛?br>
CWinApp::CWinApp(LPCTSTR lpszAppName)
{
銆if (lpszAppName != NULL)
銆銆m_pszAppName = _tcsdup(lpszAppName);
銆else
銆銆m_pszAppName = NULL;

銆// initialize CWinThread state
銆AFX_MODULE_STATE *pModuleState = _AFX_CMDTARGET_GETSTATE();
銆AFX_MODULE_THREAD_STATE *pThreadState = pModuleState->m_thread;
銆ASSERT(AfxGetThread() == NULL);
銆pThreadState->m_pCurrentWinThread = this;
銆ASSERT(AfxGetThread() == this);
銆m_hThread = ::GetCurrentThread();
銆m_nThreadID = ::GetCurrentThreadId();

銆// initialize CWinApp state
銆ASSERT(afxCurrentWinApp == NULL); // only one CWinApp object please
銆pModuleState->m_pCurrentWinApp = this;
銆ASSERT(AfxGetApp() == this);

銆// in non-running state until WinMain
銆m_hInstance = NULL;
銆m_pszHelpFilePath = NULL;
銆m_pszProfileName = NULL;
銆m_pszRegistryKey = NULL;
銆m_pszExeName = NULL;
銆m_pRecentFileList = NULL;
銆m_pDocManager = NULL;
銆m_atomApp = m_atomSystemTopic = NULL; //寰蔣鎳掗錛熸垨鑰呬粬璁や負
銆//榪欐牱榪炵瓑鍚箟鏇存槑紜紵
銆m_lpCmdLine = NULL;
銆m_pCmdInfo = NULL;

銆// initialize wait cursor state
銆m_nWaitCursorCount = 0;
銆m_hcurWaitCursorRestore = NULL;

銆// initialize current printer state
銆m_hDevMode = NULL;
銆m_hDevNames = NULL;
銆m_nNumPreviewPages = 0; // not specified (defaults to 1)

銆// initialize DAO state
銆m_lpfnDaoTerm = NULL; // will be set if AfxDaoInit called

銆// other initialization
銆m_bHelpMode = FALSE;
銆m_nSafetyPoolSize = 512; // default size
}

銆銆寰堟樉鐒訛紝theApp鎴愬憳鍙橀噺閮借璧嬩簣OS鍚姩鐨勮繖涓綋鍓嶇嚎紼嬬浉鍏崇殑鍊鹼紝濡備唬鐮侊細

m_hThread = ::GetCurrentThread();//theApp鐨勭嚎紼嬪彞鏌勭瓑浜庡綋鍓嶇嚎紼嬪彞鏌?
m_nThreadID = ::GetCurrentThreadId();//theApp鐨勭嚎紼婭D絳変簬褰撳墠綰跨▼ID

銆銆鎵浠WinApp綾誨嚑涔庡彧鏄負MFC紼嬪簭鐨勭涓涓嚎紼嬮噺韜畾鍒剁殑錛屽畠涓嶉渶瑕佷篃涓嶈兘琚獳fxBeginThread鎴杢heApp.CreateThread"鍐嶆"鍚姩銆傝繖灝辨槸CWinApp綾誨拰theApp鍏ㄥ眬鍙橀噺鐨勫唴娑碉紒濡傛灉浣犺鍐嶅鍔犱竴涓猆I綰跨▼錛屼笉瑕佺戶鎵跨被CWinApp錛岃屽簲緇ф壙綾籆WinThread銆傝屽弬鑰冪1鑺傦紝鐢變簬鎴戜滑涓鑸互涓葷嚎紼嬶紙鍦∕FC紼嬪簭閲屽疄闄呬笂灝辨槸OS鍚姩鐨勭涓涓嚎紼嬶級澶勭悊鎵鏈夌獥鍙g殑娑堟伅錛屾墍浠ユ垜浠嚑涔庢病鏈夊啀鍚姩UI綰跨▼鐨勯渶姹傦紒



Sandy 2008-11-02 22:36 鍙戣〃璇勮
]]>
杞細Windows澶氱嚎紼嬪浠誨姟璁捐鍒濇 http://www.shnenglu.com/SpringSnow/articles/65789.htmlSandySandySun, 02 Nov 2008 14:35:00 GMThttp://www.shnenglu.com/SpringSnow/articles/65789.htmlhttp://www.shnenglu.com/SpringSnow/comments/65789.htmlhttp://www.shnenglu.com/SpringSnow/articles/65789.html#Feedback0http://www.shnenglu.com/SpringSnow/comments/commentRss/65789.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/65789.htmlhttp://www.shnenglu.com/ivenher/articles/983.html
錛誨墠璦錛氾冀褰撳墠嫻佽鐨刉indows鎿嶄綔緋葷粺錛屽畠鑳藉悓鏃惰繍琛屽嚑涓▼搴?鐙珛榪愯鐨勭▼搴忓張縐頒箣涓鴻繘紼?錛屽浜庡悓涓涓▼搴忥紝瀹冨張鍙互鍒嗘垚鑻ュ共涓嫭绔嬬殑鎵ц嫻侊紝鎴戜滑縐頒箣涓虹嚎紼嬶紝綰跨▼鎻愪緵浜嗗浠誨姟澶勭悊鐨勮兘鍔涖傜敤榪涚▼鍜岀嚎紼嬬殑瑙傜偣鏉ョ爺絀惰蔣浠舵槸褰撲粖鏅亶閲囩敤鐨勬柟娉曪紝榪涚▼鍜岀嚎紼嬬殑姒傚康鐨勫嚭鐜幫紝瀵規彁楂樿蔣浠剁殑騫惰鎬ф湁鐫閲嶈鐨勬剰涔夈傜幇鍦ㄧ殑搴旂敤杞歡鏃犱竴涓嶆槸澶氱嚎紼嬪浠誨姟澶勭悊錛屽崟綰垮煄鐨勮蔣浠舵槸涓嶅彲鎯寵薄鐨勩傚洜姝ゆ帉鎻″綰跨▼澶氫換鍔¤璁℃柟娉曞姣忎釜紼嬪簭鍛橀兘鏄繀闇瑕佹帉鎻$殑銆傛湰鏂囬拡瀵瑰綰跨▼鎶鏈湪搴旂敤涓粡甯擱亣鍒扮殑闂錛屽綰跨▼闂寸殑閫氫俊銆佸悓姝ョ瓑錛屽瀹冧滑鍒嗗埆榪涜鎺㈣銆?

銆銆 涓銆?鐞嗚В綰跨▼

銆銆 瑕佽瑙g嚎紼嬶紝涓嶅緱涓嶈涓涓嬭繘紼嬶紝榪涚▼鏄簲鐢ㄧ▼搴忕殑鎵ц瀹炰緥錛屾瘡涓繘紼嬫槸鐢辯鏈夌殑铏氭嫙鍦板潃絀洪棿銆佷唬鐮併佹暟鎹拰鍏跺畠緋葷粺璧勬簮緇勬垚銆傝繘紼嬪湪榪愯鏃跺垱寤虹殑璧勬簮闅忕潃榪涚▼鐨勭粓姝㈣屾浜°傜嚎紼嬬殑鍩烘湰鎬濇兂寰堢畝鍗曪紝瀹冩槸涓涓嫭绔嬬殑鎵ц嫻侊紝鏄繘紼嬪唴閮ㄧ殑涓涓嫭绔嬬殑鎵ц鍗曞厓錛岀浉褰撲簬涓涓瓙紼嬪簭錛屽畠瀵瑰簲Visual C++涓殑CwinThread綾葷殑瀵硅薄銆傚崟鐙竴涓墽琛岀▼搴忚繍琛屾椂錛岀己鐪佺殑榪愯鍖呭惈鐨勪竴涓富綰跨▼錛屼富綰跨▼浠ュ嚱鏁板湴鍧鐨勫艦寮忥紝濡俶ain鎴朩inMain鍑芥暟錛屾彁渚涚▼搴忕殑鍚姩鐐癸紝褰撲富綰跨▼緇堟鏃訛紝榪涚▼涔熼殢涔嬬粓姝紝浣嗘牴鎹渶瑕侊紝搴旂敤紼嬪簭鍙堝彲浠ュ垎瑙f垚璁稿鐙珛鎵ц鐨勭嚎紼嬶紝姣忎釜綰跨▼騫惰鐨勮繍琛屽湪鍚屼竴榪涚▼涓?

銆銆 涓涓繘紼嬩腑鐨勬墍鏈夌嚎紼嬮兘鍦ㄨ榪涚▼鐨勮櫄鎷熷湴鍧絀洪棿涓紝浣跨敤璇ヨ繘紼嬬殑鍏ㄥ眬鍙橀噺鍜岀郴緇熻祫婧愩傛搷浣滅郴緇熺粰姣忎釜綰跨▼鍒嗛厤涓嶅悓鐨凜PU鏃墮棿鐗囷紝鍦ㄦ煇涓涓椂鍒伙紝CPU鍙墽琛屼竴涓椂闂寸墖鍐呯殑綰跨▼錛屽涓椂闂寸墖涓殑鐩稿簲綰跨▼鍦–PU鍐呰疆嫻佹墽琛岋紝鐢變簬姣忎釜鏃墮棿鐗囨椂闂村緢鐭紝鎵浠ュ鐢ㄦ埛鏉ヨ錛屼豢浣涘悇涓嚎紼嬪湪璁$畻鏈轟腑鏄茍琛屽鐞嗙殑銆傛搷浣滅郴緇熸槸鏍規嵁綰跨▼鐨勪紭鍏堢駭鏉ュ畨鎺扖PU鐨勬椂闂達紝浼樺厛綰ч珮鐨勭嚎紼嬩紭鍏堣繍琛岋紝浼樺厛綰т綆鐨勭嚎紼嬪垯緇х畫絳夊緟銆?

銆銆 綰跨▼琚垎涓轟袱縐嶏細鐢ㄦ埛鐣岄潰綰跨▼鍜屽伐浣滅嚎紼嬶紙鍙堢О涓哄悗鍙扮嚎紼嬶級銆傜敤鎴風晫闈㈢嚎紼嬮氬父鐢ㄦ潵澶勭悊鐢ㄦ埛鐨勮緭鍏ュ茍鍝嶅簲鍚勭浜嬩歡鍜屾秷鎭紝鍏跺疄錛屽簲鐢ㄧ▼搴忕殑涓繪墽琛岀嚎紼婥WinAPP瀵硅薄灝辨槸涓涓敤鎴風晫闈㈢嚎紼嬶紝褰撳簲鐢ㄧ▼搴忓惎鍔ㄦ椂鑷姩鍒涘緩鍜屽惎鍔紝鍚屾牱瀹冪殑緇堟涔熸剰鍛崇潃璇ョ▼搴忕殑緇撴潫錛岃繘鍩庣粓姝€傚伐浣滆呯嚎紼嬬敤鏉ユ墽琛岀▼搴忕殑鍚庡彴澶勭悊浠誨姟錛屾瘮濡傝綆椼佽皟搴︺佸涓插彛鐨勮鍐欐搷浣滅瓑錛屽畠鍜岀敤鎴風晫闈㈢嚎紼嬬殑鍖哄埆鏄畠涓嶇敤浠嶤winThread綾繪淳鐢熸潵鍒涘緩錛屽瀹冩潵璇存渶閲嶈鐨勬槸濡備綍瀹炵幇宸ヤ綔綰跨▼浠誨姟鐨勮繍琛屾帶鍒跺嚱鏁般傚伐浣滅嚎紼嬪拰鐢ㄦ埛鐣岄潰綰跨▼鍚姩鏃惰璋冪敤鍚屼竴涓嚱鏁扮殑涓嶅悓鐗堟湰錛涙渶鍚庨渶瑕佽鑰呮槑鐧界殑鏄紝涓涓繘紼嬩腑鐨勬墍鏈夌嚎紼嬪叡浜畠浠埗榪涚▼鐨勫彉閲忥紝浣嗗悓鏃舵瘡涓嚎紼嬪彲浠ユ嫢鏈夎嚜宸辯殑鍙橀噺銆?
銆銆 浜屻?綰跨▼鐨勭鐞嗗拰鎿嶄綔

銆銆 1錛?綰跨▼鐨勫惎鍔?

銆銆 鍒涘緩涓涓敤鎴風晫闈㈢嚎紼嬶紝棣栧厛瑕佷粠綾籆winThread浜х敓涓涓淳鐢熺被錛屽悓鏃跺繀欏諱嬌鐢―ECLARE_DYNCREATE鍜孖MPLEMENT_DYNCREATE鏉ュ0鏄庡拰瀹炵幇榪欎釜CwinThread媧劇敓綾匯?

銆銆 絎簩姝ユ槸鏍規嵁闇瑕侀噸杞借媧劇敓綾葷殑涓浜涙垚鍛樺嚱鏁板錛欵xitInstance()錛汭nitInstance()錛汷nIdle();PreTranslateMessage()絳夊嚱鏁幫紝鏈鍚庡惎鍔ㄨ鐢ㄦ埛鐣岄潰綰跨▼錛岃皟鐢ˋfxBeginThread()鍑芥暟鐨勪竴涓増鏈細CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );鍏朵腑絎竴涓弬鏁頒負鎸囧悜瀹氫箟鐨勭敤鎴風晫闈㈢嚎紼嬬被鎸囬拡鍙橀噺錛岀浜屼釜鍙傛暟涓虹嚎紼嬬殑浼樺厛綰э紝絎笁涓弬鏁頒負綰跨▼鎵瀵瑰簲鐨勫爢鏍堝ぇ灝忥紝絎洓涓弬鏁頒負綰跨▼鍒涘緩鏃剁殑闄勫姞鏍囧織錛岀己鐪佷負姝e父鐘舵侊紝濡備負CREATE_SUSPENDED鍒欑嚎紼嬪惎鍔ㄥ悗涓烘寕璧風姸鎬併?

銆銆 瀵逛簬宸ヤ綔綰跨▼鏉ヨ錛屽惎鍔ㄤ竴涓嚎紼嬶紝棣栧厛闇瑕佺紪鍐欎竴涓笇鏈涗笌搴旂敤紼嬪簭鐨勫叾浣欓儴鍒嗗茍琛岃繍琛岀殑鍑芥暟濡侳un1()錛屾帴鐫瀹氫箟涓涓寚鍚慍winThread瀵硅薄鐨勬寚閽堝彉閲?pThread,璋冪敤AfxBeginThread(Fun1,param,priority)鍑芥暟錛岃繑鍥炲間粯緇檖Thread鍙橀噺鐨勫悓鏃朵竴騫跺惎鍔ㄨ綰跨▼鏉ユ墽琛屼笂闈㈢殑Fun1()鍑芥暟錛屽叾涓璅un1鏄嚎紼嬭榪愯鐨勫嚱鏁扮殑鍚嶅瓧錛屼篃鏃㈡槸涓婇潰鎵璇寸殑鎺у埗鍑芥暟鐨勫悕瀛楋紝param鏄噯澶囦紶閫佺粰綰跨▼鍑芥暟Fun1鐨勪換鎰?2浣嶅鹼紝priority鍒欐槸瀹氫箟璇ョ嚎紼嬬殑浼樺厛綰у埆錛屽畠鏄瀹氫箟鐨勫父鏁幫紝璇昏呭彲鍙傝僊SDN銆?

銆銆 2錛庣嚎紼嬬殑浼樺厛綰?

銆銆 浠ヤ笅鐨凜winThread綾葷殑鎴愬憳鍑芥暟鐢ㄤ簬綰跨▼浼樺厛綰х殑鎿嶄綔錛?

int GetThreadPriority();
BOOL SetThradPriority()(int nPriority);

涓婅堪鐨勪簩涓嚱鏁板垎鍒敤鏉ヨ幏鍙栧拰璁劇疆綰跨▼鐨勪紭鍏堢駭錛岃繖閲岀殑浼樺厛綰э紝鏄浉瀵逛簬璇ョ嚎紼嬫墍澶勭殑浼樺厛鏉冨眰嬈¤岃█鐨勶紝澶勪簬鍚屼竴浼樺厛鏉冨眰嬈$殑綰跨▼錛屼紭鍏堢駭楂樼殑綰跨▼鍏堣繍琛岋紱澶勪簬涓嶅悓浼樺厛鏉冨眰嬈′笂鐨勭嚎紼嬶紝璋佺殑浼樺厛鏉冨眰嬈¢珮錛岃皝鍏堣繍琛屻傝嚦浜庝紭鍏堢駭璁劇疆鎵闇鐨勫父鏁幫紝鑷繁鍙傝僊SDN灝卞彲浠ヤ簡錛岃娉ㄦ剰鐨勬槸瑕佹兂璁劇疆綰跨▼鐨勪紭鍏堢駭錛岃繖涓嚎紼嬪湪鍒涘緩鏃跺繀欏誨叿鏈塗HREAD_SET_INFORMATION璁塊棶鏉冮檺銆傚浜庣嚎紼嬬殑浼樺厛鏉冨眰嬈$殑璁劇疆錛孋winThread綾繪病鏈夋彁渚涚浉搴旂殑鍑芥暟錛屼絾鏄彲浠ラ氳繃Win32 SDK鍑芥暟GetPriorityClass()鍜孲etPriorityClass()鏉ュ疄鐜般?

銆銆 3錛庣嚎紼嬬殑鎮寕銆佹仮澶?

銆銆 CwinThread綾諱腑鍖呭惈浜嗗簲鐢ㄧ▼搴忔偓鎸傚拰鎭㈠瀹冩墍鍒涘緩鐨勭嚎紼嬬殑鍑芥暟錛屽叾涓璖uspendThread()鐢ㄦ潵鎮寕綰跨▼錛屾殏鍋滅嚎紼嬬殑鎵ц錛汻esumeThread()鐢ㄦ潵鎭㈠綰跨▼鐨勬墽琛屻傚鏋滀綘瀵逛竴涓嚎紼嬭繛緇嫢騫叉鎵цSuspendThread()錛屽垯闇瑕佽繛緇墽琛岀浉搴旀鐨凴esumeThread()鏉ユ仮澶嶇嚎紼嬬殑榪愯銆?

銆銆 4錛庣粨鏉熺嚎紼?

銆銆 緇堟綰跨▼鏈変笁縐嶉斿緞錛岀嚎紼嬪彲浠ュ湪鑷韓鍐呴儴璋冪敤AfxEndThread()鏉ョ粓姝㈣嚜韜殑榪愯錛涘彲浠ュ湪綰跨▼鐨勫閮ㄨ皟鐢˙OOL TerminateThread( HANDLE hThread, DWORD dwExitCode )鏉ュ己琛岀粓姝竴涓嚎紼嬬殑榪愯錛岀劧鍚庤皟鐢–loseHandle錛堬級鍑芥暟閲婃斁綰跨▼鎵鍗犵敤鐨勫爢鏍堬紱絎笁縐嶆柟娉曟槸鏀瑰彉鍏ㄥ眬鍙橀噺錛屼嬌綰跨▼鐨勬墽琛屽嚱鏁拌繑鍥烇紝鍒欒綰跨▼緇堟銆備笅闈互絎笁縐嶆柟娉曚負渚嬶紝緇欏嚭閮ㄥ垎浠g爜錛?

////////////////////////////////////////////////////////////////
//////CtestView message handlers
/////Set to True to end thread
Bool bend=FALSE;//瀹氫箟鐨勫叏灞鍙橀噺錛岀敤浜庢帶鍒剁嚎紼嬬殑榪愯
//The Thread Function
UINT ThreadFunction(LPVOID pParam)//綰跨▼鍑芥暟
{
while(!bend)
{Beep(100,100);
Sleep(1000);
}
return 0;
}
CwinThread *pThread;
HWND hWnd;
/////////////////////////////////////////////////////////////
Void CtestView::OninitialUpdate()
{
hWnd=GetSafeHwnd();
pThread=AfxBeginThread(ThradFunction,hWnd);//鍚姩綰跨▼
pThread->m_bAutoDelete=FALSE;//綰跨▼涓烘墜鍔ㄥ垹闄?
Cview::OnInitialUpdate();
}
////////////////////////////////////////////////////////////////
Void CtestView::OnDestroy()
{ bend=TRUE;//鏀瑰彉鍙橀噺錛岀嚎紼嬬粨鏉?
WaitForSingleObject(pThread->m_hThread,INFINITE);//絳夊緟綰跨▼緇撴潫
delete pThread;//鍒犻櫎綰跨▼
Cview::OnDestroy();
}
銆銆 涓夈?綰跨▼涔嬮棿鐨勯氫俊

銆銆 閫氬父鎯呭喌涓嬶紝涓涓綰х嚎紼嬭涓轟富綰跨▼瀹屾垚鏌愮鐗瑰畾綾誨瀷鐨勪換鍔★紝榪欏氨闅愬惈鐫琛ㄧず鍦ㄤ富綰跨▼鍜屾綰х嚎紼嬩箣闂撮渶瑕佸緩绔嬩竴涓氫俊鐨勯氶亾銆備竴鑸儏鍐典笅錛屾湁涓嬮潰鐨勫嚑縐嶆柟娉曞疄鐜拌繖縐嶉氫俊浠誨姟錛氫嬌鐢ㄥ叏灞鍙橀噺錛堜笂涓鑺傜殑渚嬪瓙鍏跺疄浣跨敤鐨勫氨鏄繖縐嶆柟娉曪級銆佷嬌鐢ㄤ簨浠跺璞°佷嬌鐢ㄦ秷鎭傝繖閲屾垜浠富瑕佷粙緇嶅悗涓ょ鏂規硶銆?

銆銆 1錛?鍒╃敤鐢ㄦ埛瀹氫箟鐨勬秷鎭氫俊

銆銆 鍦╓indows紼嬪簭璁捐涓紝搴旂敤紼嬪簭鐨勬瘡涓涓嚎紼嬮兘鎷ユ湁鑷繁鐨勬秷鎭槦鍒楋紝鐢氳嚦宸ヤ綔綰跨▼涔熶笉渚嬪錛岃繖鏍蜂竴鏉ワ紝灝變嬌寰楃嚎紼嬩箣闂村埄鐢ㄦ秷鎭潵浼犻掍俊鎭氨鍙樼殑闈炲父綆鍗曘傞鍏堢敤鎴瘋瀹氫箟涓涓敤鎴鋒秷鎭紝濡備笅鎵紺猴細#define WM_USERMSG WMUSER+100錛涘湪闇瑕佺殑鏃跺欙紝鍦ㄤ竴涓嚎紼嬩腑璋冪敤

錛氾細PostMessage((HWND)param,WM_USERMSG,0,0)
鎴?
CwinThread::PostThradMessage()

鏉ュ悜鍙﹀涓涓嚎紼嬪彂閫佽繖涓秷鎭紝涓婅堪鍑芥暟鐨勫洓涓弬鏁板垎鍒槸娑堟伅灝嗚鍙戦佸埌鐨勭洰鐨勭獥鍙g殑鍙ユ焺銆佽鍙戦佺殑娑堟伅鏍囧織絎︺佹秷鎭殑鍙傛暟WPARAM鍜孡PARAM銆備笅闈㈢殑浠g爜鏄涓婅妭浠g爜鐨勪慨鏀癸紝淇敼鍚庣殑緇撴灉鏄湪綰跨▼緇撴潫鏃舵樉紺轟竴涓璇濇錛屾彁紺虹嚎紼嬬粨鏉燂細

UINT ThreadFunction(LPVOID pParam)
{
while(!bend)
{
Beep(100,100);
Sleep(1000);
}
錛氾細PostMessage(hWnd,WM_USERMSG,0,0)錛?
return 0;
}
////////WM_USERMSG娑堟伅鐨勫搷搴斿嚱鏁頒負OnThreadended(WPARAM wParam,LPARAM lParam)
LONG CTestView::OnThreadended(WPARAM wParam,LPARAM lParam)
{
AfxMessageBox("Thread ended.");
Retrun 0;
}

涓婇潰鐨勪緥瀛愭槸宸ヤ綔鑰呯嚎紼嬪悜鐢ㄦ埛鐣岄潰綰跨▼鍙戦佹秷鎭紝瀵逛簬宸ヤ綔鑰呯嚎紼嬶紝濡傛灉瀹冪殑璁捐妯″紡涔熸槸娑堟伅椹卞姩鐨勶紝閭d箞璋冪敤鑰呭彲浠ュ悜瀹冨彂閫佸垵濮嬪寲銆侀鍑恒佹墽琛屾煇縐嶇壒瀹氱殑澶勭悊絳夋秷鎭紝璁╁畠鍦ㄥ悗鍙板畬鎴愩傚湪鎺у埗鍑芥暟涓彲浠ョ洿鎺ヤ嬌鐢細錛欸etMessage()榪欎釜SDK鍑芥暟榪涜娑堟伅鍒嗘鍜屽鐞嗭紝鑷繁瀹炵幇涓涓秷鎭驚鐜侴etMessage()鍑芥暟鍦ㄥ垽鏂綰跨▼鐨勬秷鎭槦鍒椾負絀烘椂錛岀嚎紼嬪皢緋葷粺鍒嗛厤緇欏畠鐨勬椂闂寸墖璁╃粰鍏跺畠綰跨▼錛屼笉鏃犳晥鐨勫崰鐢–PU鐨勬椂闂達紝濡傛灉娑堟伅闃熷垪涓嶄負絀猴紝灝辮幏鍙栬繖涓秷鎭紝鍒ゆ柇榪欎釜娑堟伅鐨勫唴瀹瑰茍榪涜鐩稿簲鐨勫鐞嗐?

銆銆 2錛庣敤浜嬩歡瀵硅薄瀹炵幇閫氫俊

銆銆 鍦ㄧ嚎紼嬩箣闂翠紶閫掍俊鍙瘋繘琛岄氫俊姣旇緝澶嶆潅鐨勬柟娉曟槸浣跨敤浜嬩歡瀵硅薄錛岀敤MFC鐨凜event綾葷殑瀵硅薄鏉ヨ〃紺恒備簨浠跺璞″浜庝袱縐嶇姸鎬佷箣涓錛氭湁淇″彿鍜屾棤淇″彿錛岀嚎紼嬪彲浠ョ洃瑙嗗浜庢湁淇″彿鐘舵佺殑浜嬩歡錛屼互渚垮湪閫傚綋鐨勬椂鍊欐墽琛屽浜嬩歡鐨勬搷浣溿備笂榪頒緥瀛愪唬鐮佷慨鏀瑰涓嬶細

////////////////////////////////////////////////////////////////////
Cevent threadStart,threadEnd;
////////////////////////////////////////////////////////////////////
UINT ThreadFunction(LPVOID pParam)
{
錛氾細WaitForSingleObject(threadStart.m_hObject,INFINITE);
AfxMessageBox("Thread start.");
while(!bend)
{
Beep(100,100);
Sleep(1000);
Int result=::WaitforSingleObject(threadEnd.m_hObject,0);
//絳夊緟threadEnd浜嬩歡鏈変俊鍙鳳紝鏃犱俊鍙鋒椂綰跨▼鍦ㄨ繖閲屾偓鍋?
If(result==Wait_OBJECT_0)
Bend=TRUE;
}
錛氾細PostMessage(hWnd,WM_USERMSG,0,0)錛?
return 0;
}
/////////////////////////////////////////////////////////////
Void CtestView::OninitialUpdate()
{
hWnd=GetSafeHwnd();
threadStart.SetEvent();//threadStart浜嬩歡鏈変俊鍙?
pThread=AfxBeginThread(ThreadFunction,hWnd);//鍚姩綰跨▼
pThread->m_bAutoDelete=FALSE;
Cview::OnInitialUpdate();
}
////////////////////////////////////////////////////////////////
Void CtestView::OnDestroy()
{ threadEnd.SetEvent();
WaitForSingleObject(pThread->m_hThread,INFINITE);
delete pThread;
Cview::OnDestroy();
}

榪愯榪欎釜紼嬪簭錛屽綋鍏抽棴紼嬪簭鏃訛紝鎵嶆樉紺烘彁紺烘錛屾樉紺?Thread ended"
銆銆 鍥涖?綰跨▼涔嬮棿鐨勫悓姝?

銆銆 鍓嶉潰鎴戜滑璁茶繃錛屽悇涓嚎紼嬪彲浠ヨ闂繘紼嬩腑鐨勫叕鍏卞彉閲忥紝鎵浠ヤ嬌鐢ㄥ綰跨▼鐨勮繃紼嬩腑闇瑕佹敞鎰忕殑闂鏄浣曢槻姝袱涓垨涓や釜浠ヤ笂鐨勭嚎紼嬪悓鏃惰闂悓涓涓暟鎹紝浠ュ厤鐮村潖鏁版嵁鐨勫畬鏁存с備繚璇佸悇涓嚎紼嬪彲浠ュ湪涓璧烽傚綋鐨勫崗璋冨伐浣滅О涓虹嚎紼嬩箣闂寸殑鍚屾銆傚墠闈竴鑺備粙緇嶇殑浜嬩歡瀵硅薄瀹為檯涓婂氨鏄竴縐嶅悓姝ュ艦寮忋俈isual C++涓嬌鐢ㄥ悓姝ョ被鏉ヨВ鍐蟲搷浣滅郴緇熺殑騫惰鎬ц屽紩璧風殑鏁版嵁涓嶅畨鍏ㄧ殑闂錛孧FC鏀寔鐨勪竷涓綰跨▼鐨勫悓姝ョ被鍙互鍒嗘垚涓ゅぇ綾伙細鍚屾瀵硅薄錛圕syncObject銆丆semaphore銆丆mutex銆丆criticalSection鍜孋event錛夊拰鍚屾璁塊棶瀵硅薄錛圕multiLock鍜孋singleLock錛夈傛湰鑺備富瑕佷粙緇嶄復鐣屽尯錛坈ritical section錛夈佷簰鏂ワ紙mutexe錛夈佷俊鍙烽噺錛坰emaphore錛夛紝榪欎簺鍚屾瀵硅薄浣垮悇涓嚎紼嬪崗璋冨伐浣滐紝紼嬪簭榪愯璧鋒潵鏇村畨鍏ㄣ?

銆銆 1錛?涓寸晫鍖?

銆銆 涓寸晫鍖烘槸淇濊瘉鍦ㄦ煇涓涓椂闂村彧鏈変竴涓嚎紼嬪彲浠ヨ闂暟鎹殑鏂規硶銆備嬌鐢ㄥ畠鐨勮繃紼嬩腑錛岄渶瑕佺粰鍚勪釜綰跨▼鎻愪緵涓涓叡浜殑涓寸晫鍖哄璞★紝鏃犺鍝釜綰跨▼鍗犳湁涓寸晫鍖哄璞★紝閮藉彲浠ヨ闂彈鍒頒繚鎶ょ殑鏁版嵁錛岃繖鏃跺欏叾瀹冪殑綰跨▼闇瑕佺瓑寰咃紝鐩村埌璇ョ嚎紼嬮噴鏀句復鐣屽尯瀵硅薄涓烘錛屼復鐣屽尯琚噴鏀懼悗錛屽彟澶栫殑綰跨▼鍙互寮哄崰榪欎釜涓寸晫鍖猴紝浠ヤ究璁塊棶鍏變韓鐨勬暟鎹備復鐣屽尯瀵瑰簲鐫涓涓狢criticalSection瀵硅薄錛屽綋綰跨▼闇瑕佽闂繚鎶ゆ暟鎹椂錛岃皟鐢ㄤ復鐣屽尯瀵硅薄鐨凩ock()鎴愬憳鍑芥暟錛涘綋瀵逛繚鎶ゆ暟鎹殑鎿嶄綔瀹屾垚涔嬪悗錛岃皟鐢ㄤ復鐣屽尯瀵硅薄鐨刄nlock()鎴愬憳鍑芥暟閲婃斁瀵逛復鐣屽尯瀵硅薄鐨勬嫢鏈夋潈錛屼互浣垮彟涓涓嚎紼嬪彲浠ュず鍙栦復鐣屽尯瀵硅薄騫惰闂彈淇濇姢鐨勬暟鎹傚悓鏃跺惎鍔ㄤ袱涓嚎紼嬶紝瀹冧滑瀵瑰簲鐨勫嚱鏁板垎鍒負WriteThread()鍜孯eadThread()錛岀敤浠ュ鍏叡鏁扮粍緇刟rray[]鎿嶄綔錛屼笅闈㈢殑浠g爜璇存槑浜嗗浣曚嬌鐢ㄤ復鐣屽尯瀵硅薄錛?

#include "afxmt.h"
int array[10],destarray[10];
CCriticalSection Section;
////////////////////////////////////////////////////////////////////////
UINT WriteThread(LPVOID param)
{Section.Lock();
for(int x=0;x<10;x++)
array[x]=x;
Section.Unlock();
}
UINT ReadThread(LPVOID param)
{
Section.Lock();
For(int x=0;x<10;x++)
Destarray[x]=array[x];
Section.Unlock();
}

涓婅堪浠g爜榪愯鐨勭粨鏋滃簲璇ユ槸Destarray鏁扮粍涓殑鍏冪礌鍒嗗埆涓?-9錛岃屼笉鏄潅涔辨棤绔犵殑鏁幫紝濡傛灉涓嶄嬌鐢ㄥ悓姝ワ紝鍒欎笉鏄繖涓粨鏋滐紝鏈夊叴瓚g殑璇昏呭彲浠ュ疄楠屼竴涓嬨?
銆銆 2錛?浜掓枼

銆銆 浜掓枼涓庝復鐣屽尯寰堢浉浼鹼紝浣嗘槸浣跨敤鏃剁浉瀵瑰鏉備竴浜涳紝瀹冧笉浠呭彲浠ュ湪鍚屼竴搴旂敤紼嬪簭鐨勭嚎紼嬮棿瀹炵幇鍚屾錛岃繕鍙互鍦ㄤ笉鍚岀殑榪涚▼闂村疄鐜板悓姝ワ紝浠庤屽疄鐜拌祫婧愮殑瀹夊叏鍏變韓銆備簰鏂ヤ笌Cmutex綾葷殑瀵硅薄鐩稿搴旓紝浣跨敤浜掓枼瀵硅薄鏃訛紝蹇呴』鍒涘緩涓涓狢SingleLock鎴朇MultiLock瀵硅薄錛岀敤浜庡疄闄呯殑璁塊棶鎺у埗錛屽洜涓鴻繖閲岀殑渚嬪瓙鍙鐞嗗崟涓簰鏂ワ紝鎵浠ユ垜浠彲浠ヤ嬌鐢–SingleLock瀵硅薄錛岃瀵硅薄鐨凩ock()鍑芥暟鐢ㄤ簬鍗犳湁浜掓枼錛孶nlock()鐢ㄤ簬閲婃斁浜掓枼銆傚疄鐜頒唬鐮佸涓嬶細

#include "afxmt.h"
int array[10],destarray[10];
CMutex Section;

/////////////////////////////////////////////////////////////
UINT WriteThread(LPVOID param)
{ CsingleLock singlelock;
singlelock (&Section);
singlelock.Lock();
for(int x=0;x<10;x++)
array[x]=x;
singlelock.Unlock();
}
UINT ReadThread(LPVOID param)
{ CsingleLock singlelock;
singlelock (&Section);
singlelock.Lock();

For(int x=0;x<10;x++)
Destarray[x]=array[x];
singlelock.Unlock();

}

銆銆 3錛?淇″彿閲?

銆銆 淇″彿閲忕殑鐢ㄦ硶鍜屼簰鏂ョ殑鐢ㄦ硶寰堢浉浼鹼紝涓嶅悓鐨勬槸瀹冨彲浠ュ悓涓鏃跺埢鍏佽澶氫釜綰跨▼璁塊棶鍚屼竴涓祫婧愶紝鍒涘緩涓涓俊鍙烽噺闇瑕佺敤Csemaphore綾誨0鏄庝竴涓璞★紝涓鏃﹀垱寤轟簡涓涓俊鍙烽噺瀵硅薄錛屽氨鍙互鐢ㄥ畠鏉ュ璧勬簮鐨勮闂妧鏈傝瀹炵幇璁℃暟澶勭悊錛屽厛鍒涘緩涓涓狢singleLock鎴朇mltiLock瀵硅薄錛岀劧鍚庣敤璇ュ璞$殑Lock()鍑芥暟鍑忓皯榪欎釜淇″彿閲忕殑璁℃暟鍊鹼紝Unlock()鍙嶄箣銆備笅闈㈢殑浠g爜鍒嗗埆鍚姩涓変釜綰跨▼錛屾墽琛屾椂鍚屾椂鏄劇ず浜屼釜娑堟伅妗嗭紝鐒跺悗10縐掑悗絎笁涓秷鎭鎵嶅緱浠ユ樉紺恒?

/////////////////////////////////////////////////////////////////
Csemaphore *semaphore;
Semaphore=new Csemaphore(2,2);
HWND hWnd=GetSafeHwnd();
AfxBeginThread(threadProc1,hWnd);
AfxBeginThread(threadProc2,hWnd);
AfxBeginThread(threadProc3,hWnd);
//////////////////////////////////////////////////////////////////////
UINT ThreadProc1(LPVOID param)
{CsingleLock singelLock(semaphore);
singleLock.Lock();
Sleep(10000);
::MessageBox((HWND)param,"Thread1 had access","Thread1",MB_OK);
return 0;
}
UINT ThreadProc2(LPVOID param)
{CSingleLock singelLock(semaphore);
singleLock.Lock();
Sleep(10000);
::MessageBox((HWND)param,"Thread2 had access","Thread2",MB_OK);
return 0;
}
UINT ThreadProc3(LPVOID param)
{CsingleLock singelLock(semaphore);
singleLock.Lock();
Sleep(10000);
::MessageBox((HWND)param,"Thread3 had access","Thread3",MB_OK);
return 0;
}


銆銆 瀵瑰鏉傜殑搴旂敤紼嬪簭鏉ヨ錛岀嚎紼嬬殑搴旂敤緇欏簲鐢ㄧ▼搴忔彁渚涗簡楂樻晥銆佸揩閫熴佸畨鍏ㄧ殑鏁版嵁澶勭悊鑳藉姏銆傛湰鏂囪榪頒簡綰跨▼涓粡甯擱亣鍒扮殑闂錛屽笇鏈涘璇昏呮湅鍙嬫湁涓瀹氱殑甯姪銆?

Sandy 2008-11-02 22:35 鍙戣〃璇勮
]]>
杞細涓涓法騫沖彴鐨?C++ 鍐呭瓨娉勬紡媯嫻嬪櫒http://www.shnenglu.com/SpringSnow/articles/65742.htmlSandySandySun, 02 Nov 2008 02:56:00 GMThttp://www.shnenglu.com/SpringSnow/articles/65742.htmlhttp://www.shnenglu.com/SpringSnow/comments/65742.htmlhttp://www.shnenglu.com/SpringSnow/articles/65742.html#Feedback0http://www.shnenglu.com/SpringSnow/comments/commentRss/65742.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/65742.html

http://www-128.ibm.com/developerworks/cn/linux/l-mleak2/index.html


鍐呭瓨娉勬紡瀵逛簬C/C++紼嬪簭鍛樻潵璇翠篃鍙互綆椾綔鏄釜姘告亽鐨勮瘽棰樹簡鍚с傚湪Windows涓嬶紝MFC鐨勪竴涓緢鏈夌敤鐨勫姛鑳藉氨鏄兘鍦ㄧ▼搴忚繍琛岀粨鏉熸椂鎶ュ憡鏄惁鍙戠敓浜嗗唴瀛樻硠婕忋傚湪Linux涓嬶紝鐩稿鏉ヨ灝辨病鏈夐偅涔堝鏄撲嬌鐢ㄧ殑瑙e喅鏂規浜嗭細鍍弇patrol涔嬬被鐨勭幇鏈夊伐鍏鳳紝鏄撶敤鎬с侀檮鍔犲紑閿鍜屾ц兘閮戒笉鏄緢鐞嗘兂銆傛湰鏂囧疄鐜頒竴涓瀬鏄撲簬浣跨敤銆佽法騫沖彴鐨凜++鍐呭瓨娉勬紡媯嫻嬪櫒銆傚茍瀵圭浉鍏崇殑鎶鏈棶棰樹綔涓涓嬫帰璁ㄣ?/p>

鍩烘湰浣跨敤

瀵逛簬涓嬮潰榪欐牱鐨勪竴涓畝鍗曠▼搴弔est.cpp錛?/p>
int main()
            {
            int* p1 = new int;
            char* p2 = new char[10];
            return 0;
            }
            

鎴戜滑鐨勫熀鏈渶姹傚綋鐒舵槸瀵逛簬璇ョ▼搴忔姤鍛婂瓨鍦ㄤ袱澶勫唴瀛樻硠婕忋傝鍋氬埌榪欑偣鐨勮瘽錛岄潪甯哥畝鍗曪紝鍙鎶奷ebug_new.cpp涔熺紪璇戙侀摼鎺ヨ繘鍘誨氨鍙互浜嗐傚湪Linux涓嬶紝鎴戜滑浣跨敤錛?/p>
g++ test.cpp debug_new.cpp -o test
            

杈撳嚭緇撴灉濡備笅鎵紺猴細

Leaked object at 0x805e438 (size 10, <Unknown>:0)
            Leaked object at 0x805e410 (size 4, <Unknown>:0)
            

濡傛灉鎴戜滑闇瑕佹洿娓呮櫚鐨勬姤鍛婏紝涔熷緢綆鍗曪紝鍦╰est.cpp寮澶村姞涓琛?/p>
#include "debug_new.h"
            

鍗沖彲銆傛坊鍔犺琛屽悗鐨勮緭鍑哄涓嬶細

Leaked object at 0x805e438 (size 10, test.cpp:5)
            Leaked object at 0x805e410 (size 4, test.cpp:4)
            

闈炲父綆鍗曪紒





鍥為〉棣?/font>


鑳屾櫙鐭ヨ瘑

鍦╪ew/delete鎿嶄綔涓紝C++涓虹敤鎴蜂駭鐢熶簡瀵筼perator new鍜宱perator delete鐨勮皟鐢ㄣ傝繖鏄敤鎴蜂笉鑳芥敼鍙樼殑銆俹perator new鍜宱perator delete鐨勫師鍨嬪涓嬫墍紺猴細

void *operator new(size_t) throw(std::bad_alloc);
            void *operator new[](size_t) throw(std::bad_alloc);
            void operator delete(void*) throw();
            void operator delete[](void*) throw();
            

瀵逛簬"new int"錛岀紪璇戝櫒浼氫駭鐢熶竴涓皟鐢?operator new(sizeof(int))"錛岃屽浜?new char[10]"錛岀紪璇戝櫒浼氫駭鐢?operator new[](sizeof(char) * 10)"錛堝鏋渘ew鍚庨潰璺熺殑鏄竴涓被鍚嶇殑璇濓紝褰撶劧榪樿璋冪敤璇ョ被鐨勬瀯閫犲嚱鏁幫級銆傜被浼煎湴錛屽浜?delete ptr"鍜?delete[] ptr"錛岀紪璇戝櫒浼氫駭鐢?operator delete(ptr)"璋冪敤鍜?operator delete[](ptr)"璋冪敤錛堝鏋減tr鐨勭被鍨嬫槸鎸囧悜瀵硅薄鐨勬寚閽堢殑璇濓紝閭e湪operator delete涔嬪墠榪樿璋冪敤瀵硅薄鐨勬瀽鏋勫嚱鏁幫級銆傚綋鐢ㄦ埛娌℃湁鎻愪緵榪欎簺鎿嶄綔絎︽椂錛岀紪璇戠郴緇熻嚜鍔ㄦ彁渚涘叾瀹氫箟錛涜屽綋鐢ㄦ埛鑷繁鎻愪緵浜嗚繖浜涙搷浣滅鏃訛紝灝辮鐩栦簡緙栬瘧緋葷粺鎻愪緵鐨勭増鏈紝浠庤屽彲鑾峰緱瀵瑰姩鎬佸唴瀛樺垎閰嶆搷浣滅殑綺劇‘璺熻釜鍜屾帶鍒躲?/p>

鍚屾椂錛屾垜浠繕鍙互浣跨敤placement new鎿嶄綔絎︽潵璋冩暣operator new鐨勮涓恒傛墍璋損lacement new錛屾槸鎸囧甫鏈夐檮鍔犲弬鏁扮殑new鎿嶄綔絎︼紝姣斿錛屽綋鎴戜滑鎻愪緵浜嗕竴涓師鍨嬩負

void* operator new(size_t size, const char* file, int line);
            

鐨勬搷浣滅鏃訛紝鎴戜滑灝卞彲浠ヤ嬌鐢?new("hello", 123) int"鏉ヤ駭鐢熶竴涓皟鐢?operator new(sizeof(int), "hello", 123)"銆傝繖鍙互鏄浉褰撶伒媧葷殑銆傚張濡傦紝C++鏍囧噯瑕佹眰緙栬瘧鍣ㄦ彁渚涚殑涓涓猵lacement new鎿嶄綔絎︽槸

void* operator new(size_t size, const std::nothrow_t&);
            

鍏朵腑錛宯othrow_t閫氬父鏄竴涓┖緇撴瀯錛堝畾涔変負"struct nothrow_t {};"錛夛紝鍏跺敮涓鐩殑鏄彁渚涚紪璇戝櫒涓涓彲鏍規嵁閲嶈澆瑙勫垯璇嗗埆鍏蜂綋璋冪敤鐨勭被鍨嬨傜敤鎴蜂竴鑸畝鍗曞湴浣跨敤"new(std::nothrow) 綾誨瀷"錛坣othrow鏄竴涓猲othrow_t綾誨瀷鐨勫父閲忥級鏉ヨ皟鐢ㄨ繖涓猵lacement new鎿嶄綔絎︺傚畠涓庢爣鍑唍ew鐨勫尯鍒槸錛宯ew鍦ㄥ垎閰嶅唴瀛樺け璐ユ椂浼氭姏鍑哄紓甯革紝鑰?new(std::nothrow)"鍦ㄥ垎閰嶅唴瀛樺け璐ユ椂浼氳繑鍥炰竴涓┖鎸囬拡銆?/p>

瑕佹敞鎰忕殑鏄紝娌℃湁瀵瑰簲鐨?delete(std::nothrow) ptr"鐨勮娉曪紱涓嶈繃鍚庢枃浼氭彁鍒板彟涓涓浉鍏抽棶棰樸?/p>

瑕佽繘涓姝ヤ簡瑙d互涓婂叧浜嶤++璇█鐗規х殑淇℃伅錛岃鍙傞槄[Stroustrup1997]錛岀壒鍒槸6.2.6銆?0.4.11銆?5.6銆?9.4.5鍜孊.3.4鑺傘傝繖浜汣++璇█鐗規ф槸鐞嗚В鏈疄鐜扮殑鍏抽敭銆?/p>



鍥為〉棣?/font>


媯嫻嬪師鐞?/span>

鍜屽叾瀹冧竴浜涘唴瀛樻硠婕忔嫻嬬殑鏂瑰紡綾諱技錛宒ebug_new涓彁渚涗簡operator new閲嶈澆錛屽茍浣跨敤浜嗗畯鍦ㄧ敤鎴風▼搴忎腑榪涜鏇挎崲銆俤ebug_new.h涓殑鐩稿叧閮ㄥ垎濡備笅錛?/p>
void* operator new(size_t size, const char* file, int line);
            void* operator new[](size_t size, const char* file, int line);
            #define new DEBUG_NEW
            #define DEBUG_NEW new(__FILE__, __LINE__)
            

鎷夸笂闈㈠姞鍏ebug_new.h鍖呭惈鍚庣殑test.cpp鏉ヨ錛?new char[10]"鍦ㄩ澶勭悊鍚庝細鍙樻垚"new("test.cpp", 4) char[10]"錛岀紪璇戝櫒浼氭嵁姝や駭鐢熶竴涓?operator new[](sizeof(char) * 10, "test.cpp", 4)"璋冪敤銆傞氳繃鍦╠ebug_new.cpp涓嚜瀹氫箟"operator new(size_t, const char*, int)"鍜?operator delete(void*)"錛堜互鍙?operator new[]…"鍜?operator delete[]…"錛涗負閬垮厤琛屾枃绱禈錛屼互涓嬩笉鐗瑰埆鎸囧嚭錛岃鍒皁perator new鍜宱perator delete鍧囧悓鏃跺寘鍚暟緇勭増鏈級錛屾垜鍙互璺熻釜鎵鏈夌殑鍐呭瓨鍒嗛厤璋冪敤錛屽茍鍦ㄦ寚瀹氱殑媯鏌ョ偣涓婂涓嶅尮閰嶇殑new鍜宒elete鎿嶄綔榪涜鎶ヨ銆傚疄鐜板彲浠ョ浉褰撶畝鍗曪紝鐢╩ap璁板綍鎵鏈夊垎閰嶇殑鍐呭瓨鎸囬拡灝卞彲浠ヤ簡錛歯ew鏃跺線map閲屽姞涓涓寚閽堝強鍏跺搴旂殑淇℃伅錛宒elete鏃跺垹闄ゆ寚閽堝強瀵瑰簲鐨勪俊鎭紱delete鏃跺鏋渕ap閲屼笉瀛樺湪璇ユ寚閽堜負閿欒鍒犻櫎錛涚▼搴忛鍑烘椂濡傛灉map閲岃繕瀛樺湪鏈垹闄ょ殑鎸囬拡鍒欒鏄庢湁鍐呭瓨娉勬紡銆?/p>

涓嶈繃錛屽鏋滀笉鍖呭惈debug_new.h錛岃繖縐嶆柟娉曞氨璧蜂笉浜嗕綔鐢ㄤ簡銆備笉浠呭姝わ紝閮ㄥ垎鏂囦歡鍖呭惈debug_new.h錛岄儴鍒嗕笉鍖呭惈debug_new.h閮芥槸涓嶅彲琛岀殑銆傚洜涓鴻櫧鐒舵垜浠嬌鐢ㄤ簡涓ょ涓嶅悓鐨刼perator new --"operator new(size_t, const char*, int)"鍜?operator new(size_t)"-- 浣嗗彲鐢ㄧ殑"operator delete"榪樻槸鍙湁涓縐嶏紒浣跨敤鎴戜滑鑷畾涔夌殑"operator delete"錛屽綋鎴戜滑鍒犻櫎鐢?operator new(size_t)"鍒嗛厤鐨勬寚閽堟椂錛岀▼搴忓皢璁や負琚垹闄ょ殑鏄竴涓潪娉曟寚閽堬紒鎴戜滑澶勪簬涓涓袱闅懼鍦幫細瑕佷箞瀵硅繖縐嶆儏鍐典駭鐢熻鎶ワ紝瑕佷箞瀵歸噸澶嶅垹闄ゅ悓涓鎸囬拡涓ゆ涓嶄簣鎶ヨ錛氶兘涓嶆槸鍙帴鍙楃殑鑹ソ琛屼負銆?/p>

鐪嬫潵錛岃嚜瀹氫箟鍏ㄥ眬"operator new(size_t)"涔熸槸涓嶅彲閬垮厤鐨勪簡銆傚湪debug_new涓紝鎴戞槸榪欐牱鍋氱殑錛?/p>
void* operator new(size_t size)
            {
            return operator new(size, "<Unknown>", 0);
            }
            

浣嗗墠闈㈡弿榪扮殑鏂瑰紡鍘誨疄鐜板唴瀛樻硠婕忔嫻嬪櫒錛屽湪鏌愪簺C++鐨勫疄鐜頒腑錛堝GCC 2.95.3涓甫鐨凷GI STL錛夊伐浣滄甯革紝浣嗗湪鍙﹀涓浜涘疄鐜頒腑浼氳帿鍚嶅叾濡欏湴宕╂簝銆傚師鍥犱篃涓嶅鏉傦紝SGI STL浣跨敤浜嗗唴瀛樻睜錛屼竴嬈″垎閰嶄竴澶х墖鍐呭瓨錛屽洜鑰屼嬌鍒╃敤map鎴愪負鍙兘錛涗絾鍦ㄥ叾浠栫殑瀹炵幇鍙兘娌¤繖鏍峰仛錛屽湪map涓坊鍔犳暟鎹細璋冪敤operator new錛岃宱perator new浼氬湪map涓坊鍔犳暟鎹紝浠庤屾瀯鎴愪竴涓寰幆錛屽鑷村唴瀛樻孩鍑猴紝搴旂敤紼嬪簭绔嬪嵆宕╂簝銆傚洜姝わ紝鎴戜滑涓嶅緱涓嶅仠姝嬌鐢ㄦ柟渚跨殑STL妯℃澘錛岃屼嬌鐢ㄦ墜宸ユ瀯寤虹殑鏁版嵁緇撴瀯錛?/p>
struct new_ptr_list_t
            {
            new_ptr_list_t*		next;
            const char*			file;
            int					line;
            size_t				size;
            };
            

鎴戞渶鍒濈殑瀹炵幇鏂規硶灝辨槸姣忔鍦ㄤ嬌鐢╪ew鍒嗛厤鍐呭瓨鏃訛紝璋冪敤malloc澶氬垎閰?sizeof(new_ptr_list_t) 涓瓧鑺傦紝鎶婂垎閰嶇殑鍐呭瓨鍏ㄩ儴涓叉垚涓涓竴涓摼琛紙鍒╃敤next瀛楁錛夛紝鎶婃枃浠跺悕銆佽鍙楓佸璞″ぇ灝忎俊鎭垎鍒瓨鍏ile銆乴ine鍜宻ize瀛楁涓紝鐒跺悗榪斿洖(malloc榪斿洖鐨勬寚閽?+ sizeof(new_ptr_list_t))銆傚湪delete鏃訛紝鍒欏湪閾捐〃涓悳绱紝濡傛灉鎵懼埌鐨勮瘽錛?char*)閾捐〃鎸囬拡 + sizeof(new_ptr_list_t) == 寰呴噴鏀劇殑鎸囬拡錛夛紝鍒欒皟鏁撮摼琛ㄣ侀噴鏀懼唴瀛橈紝鎵句笉鍒扮殑璇濇姤鍛婂垹闄ら潪娉曟寚閽堝茍abort銆?/p>

鑷充簬鑷姩媯嫻嬪唴瀛樻硠婕忥紝鎴戠殑鍋氭硶鏄敓鎴愪竴涓潤鎬佸叏灞瀵硅薄錛堟牴鎹瓹++鐨勫璞$敓鍛芥湡錛屽湪紼嬪簭鍒濆鍖栨椂浼氳皟鐢ㄨ瀵硅薄鐨勬瀯閫犲嚱鏁幫紝鍦ㄥ叾閫鍑烘椂浼氳皟鐢ㄨ瀵硅薄鐨勬瀽鏋勫嚱鏁幫級錛屽湪鍏舵瀽鏋勫嚱鏁頒腑璋冪敤媯嫻嬪唴瀛樻硠婕忕殑鍑芥暟銆傜敤鎴鋒墜宸ヨ皟鐢ㄥ唴瀛樻硠婕忔嫻嬪嚱鏁板綋鐒朵篃鏄彲浠ョ殑銆?/p>

鍩烘湰瀹炵幇澶т綋灝辨槸濡傛銆?/p>



鍥為〉棣?/font>


鍙敤鎬ф敼榪?/span>

涓婅堪鏂規鏈鍒濆伐浣滃緱鐩稿綋濂斤紝鐩村埌鎴戝紑濮嬪垱寤哄ぇ閲忕殑瀵硅薄涓烘銆傜敱浜庢瘡嬈elete鏃墮渶瑕佸湪閾捐〃涓繘琛屾悳绱紝騫沖潎鎼滅儲嬈℃暟涓?閾捐〃闀垮害/2)錛岀▼搴忓緢蹇氨鎱㈠緱鍍忎箤榫熺埇銆傝櫧璇村彧鏄敤浜庤皟璇曪紝閫熷害澶參涔熸槸涓嶈兘鎺ュ彈鐨勩傚洜姝わ紝鎴戝仛浜嗕竴涓皬鏇存敼錛屾妸鎸囧悜閾捐〃澶撮儴鐨刵ew_ptr_list鏀規垚浜嗕竴涓暟緇勶紝涓涓璞℃寚閽堟斁鍦ㄥ摢涓涓摼琛ㄤ腑鍒欑敱瀹冪殑鍝堝笇鍊煎喅瀹氥?-鐢ㄦ埛鍙互鏇存敼瀹廌EBUG_NEW_HASH鍜孌EBUG_NEW_HASHTABLESIZE鐨勫畾涔夋潵璋冩暣debug_new鐨勮涓恒備粬浠殑褰撳墠鍊兼槸鎴戞祴璇曚笅鏉ユ瘮杈冩弧鎰忕殑瀹氫箟銆?/p>

浣跨敤涓垜浠彂鐜幫紝鍦ㄦ煇浜涚壒孌婃儏鍐典笅錛堣鐩存帴鍙傜湅debug_new.cpp涓叧浜嶥EBUG_NEW_FILENAME_LEN閮ㄥ垎鐨勬敞閲婏級錛屾枃浠跺悕鎸囬拡浼氬け鏁堛傚洜姝わ紝鐩墠鐨刣ebug_new鐨勭己鐪佽涓轟細澶嶅埗鏂囦歡鍚嶇殑澶?0涓瓧絎︼紝鑰屼笉鍙槸瀛樺偍鏂囦歡鍚嶇殑鎸囬拡銆傚彟澶栵紝璇鋒敞鎰忓師鍏坣ew_ptr_list_t鐨勯暱搴︿負16瀛楄妭錛岀幇鍦ㄦ槸32瀛楄妭錛岄兘鑳戒繚璇佸湪閫氬父鎯呭喌涓嬪唴瀛樺榻愩?/p>

姝ゅ錛屼負浜嗗厑璁哥▼搴忚兘鍜?new(std::nothrow) 涓璧峰伐浣滐紝鎴戜篃閲嶈澆浜唎perator new(size_t, const std::nothrow_t&) throw()錛涗笉鐒剁殑璇濓紝debug_new浼氳涓哄搴斾簬 new(nothrow) 鐨刣elete璋冪敤鍒犻櫎鐨勬槸涓涓潪娉曟寚閽堛傜敱浜巇ebug_new涓嶆姏鍑哄紓甯革紙鍐呭瓨涓嶈凍鏃剁▼搴忕洿鎺ユ姤璀﹂鍑猴級錛屾墍浠ヨ繖涓閲嶈澆鐨勬搷浣滃彧涓嶈繃鏄皟鐢?operator new(size_t) 鑰屽凡銆傝繖灝變笉鐢ㄥ璇翠簡銆?/p>

鍓嶉潰宸茬粡鎻愬埌錛岃寰楀埌綺劇‘鐨勫唴瀛樻硠婕忔嫻嬫姤鍛婏紝鍙互鍦ㄦ枃浠跺紑澶村寘鍚?debug_new.h"銆傛垜鐨勬儻甯稿仛娉曞彲浠ョ敤浣滃弬鑰冿細

#ifdef _DEBUG
            #include "debug_new.h"
            #endif
            

鍖呭惈鐨勪綅緗簲褰撳敖鍙兘鏃╋紝闄ら潪璺熺郴緇熺殑澶存枃浠訛紙鍏稿瀷鎯呭喌鏄疭TL鐨勫ご鏂囦歡錛夊彂鐢熶簡鍐茬獊銆傚湪鏌愪簺鎯呭喌涓嬶紝鍙兘浼氫笉甯屾湜debug_new閲嶅畾涔塶ew錛岃繖鏃跺彲浠ュ湪鍖呭惈debug_new.h涔嬪墠瀹氫箟DEBUG_NEW_NO_NEW_REDEFINITION錛岃繖鏍風殑璇濓紝鍦ㄧ敤鎴峰簲鐢ㄧ▼搴忎腑搴斾嬌鐢╠ebug_new鏉ヤ唬鏇縩ew錛堥『渚挎彁涓鍙ワ紝娌℃湁瀹氫箟DEBUG_NEW_NO_NEW_REDEFINITION鏃朵篃鍙互浣跨敤debug_new浠f浛new錛夈傚湪婧愭枃浠朵腑涔熻灝辮榪欐牱鍐欙細

#ifdef _DEBUG
            #define DEBUG_NEW_NO_NEW_REDEFINITION
            #include "debug_new.h"
            #else
            #define debug_new new
            #endif
            

騫跺湪闇瑕佽拷韙唴瀛樺垎閰嶇殑鏃跺欏叏閮ㄤ嬌鐢╠ebug_new錛堣冭檻浣跨敤鍏ㄥ眬鏇挎崲錛夈?/p>

鐢ㄦ埛鍙互閫夋嫨瀹氫箟DEBUG_NEW_EMULATE_MALLOC錛岃繖鏍穌ebug_new.h浼氫嬌鐢╠ebug_new鍜宒elete鏉ユā鎷焟alloc鍜宖ree鎿嶄綔錛屼嬌寰楃敤鎴風▼搴忎腑鐨刴alloc鍜宖ree鎿嶄綔涔熷彲浠ヨ璺熻釜銆傚湪浣跨敤鏌愪簺緙栬瘧鍣ㄧ殑鏃跺欙紙濡侱igital Mars C++ Compiler 8.29鍜孊orland C++ Compiler 5.5.1錛夛紝鐢ㄦ埛蹇呴』瀹氫箟NO_PLACEMENT_DELETE錛屽惁鍒欑紪璇戞棤娉曢氳繃銆傜敤鎴瘋繕鍙互浣跨敤涓や釜鍏ㄥ眬甯冨皵閲忔潵璋冩暣debug_new鐨勮涓猴細new_verbose_flag錛岀己鐪佷負false錛屽畾涔変負true鏃惰兘鍦ㄦ瘡嬈ew/delete鏃跺悜鏍囧噯閿欒杈撳嚭鏄劇ず璺熻釜淇℃伅錛沶ew_autocheck_flag錛岀己鐪佷負true錛屽嵆鍦ㄧ▼搴忛鍑烘椂鑷姩璋冪敤check_leaks媯鏌ュ唴瀛樻硠婕忥紝鏀逛負false鐨勮瘽鐢ㄦ埛蹇呴』鎵嬪伐璋冪敤check_leaks鏉ユ鏌ュ唴瀛樻硠婕忋?/p>

闇瑕佹敞鎰忕殑涓鐐規槸錛岀敱浜庤嚜鍔ㄨ皟鐢╟heck_leaks鏄湪debug_new.cpp涓殑闈欐佸璞℃瀽鏋勬椂錛屽洜姝や笉鑳戒繚璇佺敤鎴風殑鍏ㄥ眬瀵硅薄鐨勬瀽鏋勬搷浣滃彂鐢熷湪check_leaks璋冪敤涔嬪墠銆傚浜嶹indows涓婄殑MSVC錛屾垜浣跨敤浜?#pragma init_seg(lib)"鏉ヨ皟鏁村璞″垎閰嶉噴鏀劇殑欏哄簭錛屼絾寰堥仐鎲撅紝鎴戜笉鐭ラ亾鍦ㄥ叾浠栫殑涓浜涚紪璇戝櫒涓紙鐗瑰埆鏄紝鎴戞病鑳芥垚鍔熷湴鍦℅CC涓В鍐寵繖涓闂錛夋庝箞鍋氬埌榪欎竴鐐廣備負浜嗗噺灝戣鎶ヨ錛屾垜閲囧彇鐨勬柟寮忔槸鍦ㄨ嚜鍔ㄨ皟鐢ㄤ簡check_leaks涔嬪悗璁緉ew_verbose_flag涓簍rue錛涜繖鏍鳳紝灝辯畻璇姤鍛婁簡鍐呭瓨娉勬紡錛岄殢鍚庣殑delete鎿嶄綔榪樻槸浼氳鎵撳嵃鏄劇ず鍑烘潵銆傚彧瑕佹硠婕忔姤鍛婂拰delete鎶ュ憡鐨勫唴瀹逛竴鑷達紝鎴戜滑浠嶅彲浠ュ垽鏂嚭娌℃湁鍙戠敓鍐呭瓨娉勬紡銆?/p>

Debug_new涔熻兘媯嫻嬪鍚屼竴鎸囬拡閲嶅璋冪敤delete錛堟垨delete鏃犳晥鎸囬拡錛夌殑閿欒銆傜▼搴忓皢鏄劇ず閿欒鐨勬寚閽堝鹼紝騫跺己鍒惰皟鐢╝bort閫鍑恒?/p>

榪樻湁涓涓棶棰樻槸寮傚父澶勭悊銆傝繖鍊煎緱鐢ㄤ笓闂ㄧ殑涓鑺傛潵榪涜璇存槑銆?/p>



鍥為〉棣?/font>


鏋勯犲嚱鏁頒腑鐨勫紓甯?/span>

鎴戜滑鐪嬩竴涓嬩互涓嬬殑綆鍗曠▼搴忕ず渚嬶細

#include <stdexcept>
            #include <stdio.h>
            void* operator new(size_t size, int line)
            {
            printf("Allocate %u bytes on line %d\\n", size, line);
            return operator new(size);
            }
            class Obj {
            public:
            Obj(int n);
            private:
            int _n;
            };
            Obj::Obj(int n) : _n(n)
            {
            if (n == 0) {
            throw std::runtime_error("0 not allowed");
            }
            }
            int main()
            {
            try {
            Obj* p = new(__LINE__) Obj(0);
            delete p;
            } catch (const std::runtime_error& e) {
            printf("Exception: %s\\n", e.what());
            }
            }
            

鐪嬪嚭浠g爜涓湁浠涔堥棶棰樹簡鍚楋紵瀹為檯涓婏紝濡傛灉鎴戜滑鐢∕SVC緙栬瘧鐨勮瘽錛岀紪璇戝櫒鐨勮鍛婁俊鎭凡緇忓憡璇夋垜浠彂鐢熶簡浠涔堬細

test.cpp(27) : warning C4291: 'void *__cdecl operator new(unsigned int,int)' :
            no matching operator delete found; memory will not be freed if initialization throws an exception
            

濂斤紝鎶奷ebug_new.cpp閾炬帴榪涘幓銆傝繍琛岀粨鏋滃涓嬶細

Allocate 4 bytes on line 27 Exception: 0 not allowed Leaked object at 00342BE8 (size 4, <Unknown>:0) 	

鍟婂摝錛屽唴瀛樻硠婕忎簡涓嶆槸錛?/p>

褰撶劧錛岃繖縐嶆儏鍐靛茍闈炲緢甯歌銆傚彲鏄紝闅忕潃瀵硅薄瓚婃潵瓚婂鏉傦紝璋佽兘澶熶繚璇佷竴涓璞$殑瀛愬璞$殑鏋勯犲嚱鏁版垨鑰呬竴涓璞″湪鏋勯犲嚱鏁頒腑璋冪敤鐨勬墍鏈夊嚱鏁伴兘涓嶄細鎶涘嚭寮傚父錛熷茍涓旓紝瑙e喅璇ラ棶棰樼殑鏂規硶騫朵笉澶嶆潅錛屽彧鏄渶瑕佺紪璇戝櫒瀵?C++ 鏍囧噯鏈夎緝濂芥敮鎸侊紝鍏佽鐢ㄦ埛瀹氫箟 placement delete 綆楃錛圼C++1998]錛?.3.4鑺傦紱緗戜笂鍙互鎵懼埌1996騫寸殑鏍囧噯鑽夋錛屾瘮濡備笅闈㈢殑緗戝潃 http://www.comnets.rwth-aachen.de/doc/c++std/expr.html#expr.new錛夈傚湪鎴戞祴璇曠殑緙栬瘧鍣ㄤ腑錛孏CC錛?.95.3鎴栨洿楂樼増鏈紝Linux/Windows錛夊拰MSVC錛?.0鎴栨洿楂樼増鏈級娌℃湁闂錛岃孊orland C++ Compiler 5.5.1鍜孌igital Mars C++ Compiler錛堝埌v8.38涓烘鐨勬墍鏈夌増鏈級鍒欎笉鏀寔璇ラ」鐗規с傚湪涓婇潰鐨勪緥瀛愪腑錛屽鏋滅紪璇戝櫒鏀寔鐨勮瘽錛屾垜浠氨闇瑕佸0鏄庡茍瀹炵幇 operator delete(void*, int) 鏉ュ洖鏀秐ew鍒嗛厤鐨勫唴瀛樸傜紪璇戝櫒涓嶆敮鎸佺殑璇濓紝闇瑕佷嬌鐢ㄥ畯璁╃紪璇戝櫒蹇界暐鐩稿叧鐨勫0鏄庡拰瀹炵幇銆傚鏋滆璁ヾebug_new鍦˙orland C++ Compiler 5.5.1鎴朌igital Mars C++ Compiler涓嬬紪璇戠殑璇濓紝鐢ㄦ埛蹇呴』瀹氫箟瀹廚O_PLACEMENT_DELETE錛涘綋鐒訛紝鐢ㄦ埛寰楄嚜宸辨敞鎰忓皬蹇冩瀯閫犲嚱鏁頒腑鎶涘嚭寮傚父榪欎釜闂浜嗐?





鍥為〉棣?/font>


鏂規姣旇緝

IBM developerWorks涓婂垔杞戒簡媧惃鍏堢敓璁捐瀹炵幇鐨勪竴涓狶inux涓婄殑鍐呭瓨娉勬紡媯嫻嬫柟娉曪紙[媧惃2003]錛夈傛垜鐨勬柟妗堜笌鍏剁浉姣旓紝涓昏鍖哄埆濡備笅錛?/p>

浼樼偣錛?

  • 璺ㄥ鉤鍙幫細鍙嬌鐢ㄦ爣鍑嗗嚱鏁幫紝騫朵笖鍦℅CC 2.95.3/3.2錛圠inux/Windows錛夈丮SVC 6銆丏igital Mars C++ 8.29銆丅orland C++ 5.5.1絳夊涓紪璇戝櫒涓嬭皟璇曢氳繃銆傦紙铏界劧Linux鏄垜鐨勪富瑕佸紑鍙戝鉤鍙幫紝浣嗘垜鍙戠幇錛屾湁鏃跺欒兘鍦╓indows涓嬬紪璇戣繍琛屼唬鐮佽繕鏄潪甯告柟渚跨殑銆傦級
  • 鏄撶敤鎬э細鐢變簬閲嶈澆浜唎perator new(size_t)--媧惃鍏堢敓鍙噸杞戒簡operator new(size_t, const char*, int)--鍗充嬌涓嶅寘鍚垜鐨勫ご鏂囦歡涔熻兘媯嫻嬪唴瀛樻硠婕忥紱紼嬪簭閫鍑烘椂鑳借嚜鍔ㄦ嫻嬪唴瀛樻硠婕忥紱鍙互媯嫻嬬敤鎴風▼搴忥紙涓嶅寘鎷郴緇?搴撴枃浠訛級涓璵alloc/free浜х敓鐨勫唴瀛樻硠婕忋?
  • 鐏墊椿鎬э細鏈夊涓伒媧葷殑鍙厤緗」錛屽彲浣跨敤瀹忓畾涔夎繘琛岀紪璇戞椂閫夋嫨銆?
  • 鍙噸鍏ユэ細涓嶄嬌鐢ㄥ叏灞鍙橀噺錛屾病鏈夊祵濂梔elete闂銆?
  • 寮傚父瀹夊叏鎬э細鍦ㄧ紪璇戝櫒鏀寔鐨勬儏鍐典笅錛岃兘澶熷鐞嗘瀯閫犲嚱鏁頒腑鎶涘嚭鐨勫紓甯歌屼笉鍙戠敓鍐呭瓨娉勬紡銆?

 

緙虹偣錛?

  • 鍗曠嚎紼嬫ā鍨嬶細璺ㄥ鉤鍙扮殑澶氱嚎紼嬪疄鐜拌緝涓洪夯鐑︼紝鏍規嵁欏圭洰鐨勫疄闄呴渶瑕侊紝涔熶負浜嗕唬鐮佹竻鏅扮畝鍗曡搗瑙侊紝鎴戠殑鏂規涓嶆槸綰跨▼瀹夊叏鐨勶紱鎹㈠彞璇濊錛屽鏋滃涓嚎紼嬩腑鍚屾椂榪涜new鎴杁elete鎿嶄綔鐨勮瘽錛屽悗鏋滄湭瀹氫箟銆?
  • 鏈疄鐜拌繍琛屼腑鍐呭瓨娉勬紡媯嫻嬫姤鍛婃満鍒訛細娌℃湁閬囧埌榪欎釜闇姹侸錛涗笉榪囷紝濡傛灉瑕佹墜宸ヨ皟鐢╟heck_leaks鍑芥暟瀹炵幇鐨勮瘽涔熶笉鍥伴毦錛屽彧鏄法騫沖彴鎬у氨鏈夌偣闂浜嗐?
  • 涓嶈兘媯嫻嬪甫 [] 綆楃鍜屼笉甯?[] 綆楃娣風敤鐨勪笉鍖歸厤錛氫富瑕佷篃鏄渶姹傞棶棰橈紙濡傛灉瑕佷慨鏀瑰疄鐜扮殑璇濆茍涓嶅洶闅撅級銆?
  • 涓嶈兘鍦ㄩ敊璇殑delete璋冪敤鏃舵樉紺烘枃浠跺悕鍜岃鍙鳳細搴旇涓嶆槸澶ч棶棰橈紱鐢變簬鎴戦噸杞戒簡operator new(size_t)錛屽彲浠ヤ繚璇乨elete鍑洪敊鏃剁▼搴忓繀鐒舵湁闂錛屽洜鑰屾垜涓嶅彧鏄樉紺鴻鍛婁俊鎭紝鑰屼笖浼氬己鍒剁▼搴廰bort錛屽彲浠ラ氳繃璺熻釜紼嬪簭銆佹鏌bort鏃剁▼搴忕殑璋冪敤鏍堢煡閬撻棶棰樺嚭鍦ㄥ摢鍎褲?

 

鍙﹀錛岀幇鍦ㄥ凡瀛樺湪涓嶅皯鍟嗕笟鍜孫pen Source鐨勫唴瀛樻硠婕忔嫻嬪櫒錛屾湰鏂囦笉鎵撶畻涓涓鍐嶅仛姣旇緝銆侱ebug_new涓庡畠浠浉姣旓紝鍔熻兘涓婃葷殑鏉ヨ浠嶈緝寮憋紝浣嗘槸錛屽叾鑹ソ鐨勬槗鐢ㄦу拰璺ㄥ鉤鍙版с佷綆寤夌殑闄勫姞寮閿榪樻槸鍏鋒湁寰堝ぇ浼樺娍鐨勩?/p>



鍥為〉棣?/font>


鎬葷粨鍜岃璁?/span>

浠ヤ笂孌佃惤鍩烘湰涓婂凡緇忚鏄庝簡debug_new鐨勪富瑕佺壒鐐廣備笅闈㈠仛涓涓皬灝忕殑鎬葷粨銆?/p>

閲嶈澆鐨勭畻絎︼細

  • operator new(size_t, const char*, int)
  • operator new[](size_t, const char*, int)
  • operator new(size_t)
  • operator new[](size_t)
  • operator new(size_t, const std::nothrow_t&)
  • operator new[](size_t, const std::nothrow_t&)
  • operator delete(void*)
  • operator delete[](void*)
  • operator delete(void*, const char*, int)
  • operator delete[](void*, const char*, int)
  • operator delete(void*, const std::nothrow_t&)
  • operator delete[](void*, const std::nothrow_t&)

 

鎻愪緵鐨勫嚱鏁幫細

  • check_leaks()
    媯鏌ユ槸鍚﹀彂鐢熷唴瀛樻硠婕?

 

鎻愪緵鐨勫叏灞鍙橀噺

  • new_verbose_flag
    鏄惁鍦╪ew鍜宒elete鏃?緗楀棪"鍦版樉紺轟俊鎭?
  • new_autocheck_flag
    鏄惁鍦ㄧ▼搴忛鍑烘槸鑷姩媯嫻嬩竴嬈″唴瀛樻硠婕?

 

鍙噸瀹氫箟鐨勫畯錛?

  • NO_PLACEMENT_DELETE
    鍋囪緙栬瘧鍣ㄤ笉鏀寔placement delete錛堝叏灞鏈夋晥錛?
  • DEBUG_NEW_NO_NEW_REDEFINITION
    涓嶉噸瀹氫箟new錛屽亣璁劇敤鎴蜂細鑷繁浣跨敤debug_new錛堝寘鍚玠ebug_new.h鏃舵湁鏁堬級
  • DEBUG_NEW_EMULATE_MALLOC
    閲嶅畾涔塵alloc/free錛屼嬌鐢╪ew/delete榪涜妯℃嫙錛堝寘鍚玠ebug_new.h鏃舵湁鏁堬級
  • DEBUG_NEW_HASH
    鏀瑰彉鍐呭瓨鍧楅摼琛ㄥ搱甯屽肩殑綆楁硶錛堢紪璇慸ebug_new.cpp鏃舵湁鏁堬級
  • DEBUG_NEW_HASHTABLE_SIZE
    鏀瑰彉鍐呭瓨鍧楅摼琛ㄥ搱甯屾《鐨勫ぇ灝忥紙緙栬瘧debug_new.cpp鏃舵湁鏁堬級
  • DEBUG_NEW_FILENAME_LEN
    濡傛灉鍦ㄥ垎閰嶅唴瀛樻椂澶嶅埗鏂囦歡鍚嶇殑璇濓紝淇濈暀鐨勬枃浠跺悕闀垮害錛涗負0鏃跺垯鑷姩瀹氫箟DEBUG_NEW_NO_FILENAME_COPY錛堢紪璇慸ebug_new.cpp鏃舵湁鏁堬紱鍙傝鏂囦歡涓殑娉ㄩ噴錛?
  • DEBUG_NEW_NO_FILENAME_COPY
    鍒嗛厤鍐呭瓨鏃朵笉榪涜鏂囦歡鍚嶅鍒訛紝鑰屽彧鏄繚瀛樺叾鎸囬拡錛涙晥鐜囪緝楂橈紙緙栬瘧debug_new.cpp鏃舵湁鏁堬紱鍙傝鏂囦歡涓殑娉ㄩ噴錛?

 

鎴戞湰浜鴻涓猴紝debug_new鐩墠鐨勪竴涓富瑕佺己闄鋒槸涓嶆敮鎸佸綰跨▼銆傚浜庢煇涓鐗瑰畾騫沖彴錛岃鍔犲叆澶氱嚎紼嬫敮鎸佸茍涓嶅洶闅撅紝闅懼氨闅懼湪閫氱敤涓婏紙褰撶劧錛屾潯浠剁紪璇戞槸涓涓姙娉曪紝铏界劧涓嶅浼橀泤錛夈傜瓑鍒癈++鏍囧噯涓寘鍚嚎紼嬫ā鍨嬫椂錛岃繖涓棶棰樹篃璁歌兘姣旇緝瀹岀編鍦拌В鍐沖惂銆傚彟涓涓姙娉曟槸浣跨敤鍍廱oost榪欐牱鐨勭▼搴忓簱涓殑綰跨▼灝佽綾伙紝涓嶈繃錛岃繖鍙堜細澧炲姞瀵瑰叾瀹冨簱鐨勪緷璧栨?-姣曠珶boost騫朵笉鏄疌++鏍囧噯鐨勪竴閮ㄥ垎銆傚鏋滈」鐩湰韜茍涓嶇敤boost錛屽崟涓轟簡榪欎竴涓洰鐨勪嬌鐢ㄥ彟澶栦竴涓▼搴忓簱浼間箮騫朵笉鍊煎緱銆傚洜姝わ紝鎴戣嚜宸辨殏鏃跺氨涓嶅仛榪欒繘涓姝ョ殑鏀硅繘浜嗐?/p>

鍙﹀涓涓彲鑳界殑淇敼鏄繚鐣欐爣鍑唎perator new鐨勫紓甯歌涓猴紝浣垮叾鍦ㄥ唴瀛樹笉瓚崇殑鎯呭喌涓嬫姏鍑哄紓甯革紙鏅氭儏鍐碉級鎴栨槸榪斿洖NULL錛坣othrow鎯呭喌錛夛紝鑰屼笉鏄儚鐜板湪涓鏍風粓姝㈢▼搴忚繍琛岋紙鍙傝debug_new.cpp鐨勬簮浠g爜錛夈傝繖涓鍋氭硶鐨勯毦搴︿富瑕佸湪浜庡悗鑰咃細鎴戞病鎯沖嚭浠涔堟柟娉曪紝鍙互淇濈暀 new(nothrow) 鐨勮娉曪紝鍚屾椂鑳藉鎶ュ憡鏂囦歡鍚嶅拰琛屽彿錛屽茍涓旇繕鑳藉浣跨敤鏅氱殑new銆備笉榪囷紝濡傛灉涓嶄嬌鐢ㄦ爣鍑嗚娉曪紝涓寰嬩嬌鐢╠ebug_new鍜宒ebug_new_nothrow鐨勮瘽錛岄偅榪樻槸闈炲父瀹規槗瀹炵幇鐨勩?/p>

濡傛灉澶у鏈夋敼榪涙剰瑙佹垨鍏跺畠鎯蟲硶鐨勮瘽錛屾榪庢潵淇¤璁恒?/p>

debug_new 鐨勬簮浠g爜鐩墠鍙互鍦?dbg_new.zip澶勪笅杞姐?

鍦ㄨ繖綃囨枃绔犵殑鍐欏畬涔嬪悗錛屾垜緇堜簬榪樻槸瀹炵幇浜嗕竴涓嚎紼嬪畨鍏ㄧ殑鐗堟湰銆傝鐗堟湰浣跨敤浜嗕竴涓交閲忕駭鐨勮法騫沖彴浜掓枼浣撶被fast_mutex錛堢洰鍓嶆敮鎸乄in32鍜孭OSIX綰跨▼錛屽湪浣跨敤GCC錛圠inux/MinGW錛夈丮SVC鏃惰兘閫氳繃鍛戒護琛屽弬鏁拌嚜鍔ㄦ嫻嬬嚎紼嬬被鍨嬶級銆傛湁鍏磋叮鐨勮瘽鍙湪 http://mywebpage.netscape.com/yongweiwu/dbg_new.tgz涓嬭澆銆?



鍙傝冭祫鏂?

[C++1998] ISO/IEC 14882. Programming Languages-C++, 1st Edition. International Standardization Organization, International Electrotechnical Commission, American National Standards Institute, and Information Technology Industry Council, 1998

[Stroustrup1997] Bjarne Stroustrup. The C++ Programming Language, 3rd Edition. Addison-Wesley, 1997

[媧惃2003] 媧惃銆?銆婂浣曞湪 linux 涓嬫嫻嬪唴瀛樻硠婕忋?/font>錛孖BM developerWorks 涓浗緗戠珯銆?



Sandy 2008-11-02 10:56 鍙戣〃璇勮
]]>
杞細嫻呰皥鍐呭瓨娉勬紡錛堜簩錛?/title><link>http://www.shnenglu.com/SpringSnow/articles/65740.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Sun, 02 Nov 2008 02:54:00 GMT</pubDate><guid>http://www.shnenglu.com/SpringSnow/articles/65740.html</guid><wfw:comment>http://www.shnenglu.com/SpringSnow/comments/65740.html</wfw:comment><comments>http://www.shnenglu.com/SpringSnow/articles/65740.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/SpringSnow/comments/commentRss/65740.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/SpringSnow/services/trackbacks/65740.html</trackback:ping><description><![CDATA[<a >http://www.vczx.com/article/show.php?id=68</a><br><br>媯嫻嬪唴瀛樻硠婕忥細 <br>媯嫻嬪唴瀛樻硠婕忕殑鍏抽敭鏄鑳芥埅鑾蜂綇瀵瑰垎閰嶅唴瀛樺拰閲婃斁鍐呭瓨鐨勫嚱鏁扮殑璋冪敤銆傛埅鑾蜂綇榪欎袱涓嚱鏁幫紝鎴戜滑灝辮兘璺熻釜姣忎竴鍧楀唴瀛樼殑鐢熷懡鍛ㄦ湡錛屾瘮濡傦紝姣忓綋鎴愬姛鐨勫垎閰嶄竴鍧楀唴瀛樺悗錛屽氨鎶婂畠鐨勬寚閽堝姞鍏ヤ竴涓叏灞鐨刲ist涓紱姣忓綋閲婃斁涓鍧楀唴瀛橈紝鍐嶆妸瀹冪殑鎸囬拡浠巐ist涓垹闄ゃ傝繖鏍鳳紝褰撶▼搴忕粨鏉熺殑鏃跺欙紝list涓墿浣欑殑鎸囬拡灝辨槸鎸囧悜閭d簺娌℃湁琚噴鏀劇殑鍐呭瓨銆傝繖閲屽彧鏄畝鍗曠殑鎻忚堪浜嗘嫻嬪唴瀛樻硠婕忕殑鍩烘湰鍘熺悊錛岃緇嗙殑綆楁硶鍙互鍙傝Steve Maguire鐨?lt;<Writing Solid Code>>銆?<br>濡傛灉瑕佹嫻嬪爢鍐呭瓨鐨勬硠婕忥紝閭d箞闇瑕佹埅鑾蜂綇malloc/realloc/free鍜宯ew/delete灝卞彲浠ヤ簡錛堝叾瀹瀗ew/delete鏈緇堜篃鏄敤malloc/free鐨勶紝鎵浠ュ彧瑕佹埅鑾峰墠闈竴緇勫嵆鍙級銆傚浜庡叾浠栫殑娉勬紡錛屽彲浠ラ噰鐢ㄧ被浼肩殑鏂規硶錛屾埅鑾蜂綇鐩稿簲鐨勫垎閰嶅拰閲婃斁鍑芥暟銆傛瘮濡傦紝瑕佹嫻婤STR鐨勬硠婕忥紝灝遍渶瑕佹埅鑾稴ysAllocString/SysFreeString錛涜媯嫻婬MENU鐨勬硠婕忥紝灝遍渶瑕佹埅鑾稢reateMenu/ DestroyMenu銆傦紙鏈夌殑璧勬簮鐨勫垎閰嶅嚱鏁版湁澶氫釜錛岄噴鏀懼嚱鏁板彧鏈変竴涓紝姣斿錛孲ysAllocStringLen涔熷彲浠ョ敤鏉ュ垎閰岯STR錛岃繖鏃跺氨闇瑕佹埅鑾峰涓垎閰嶅嚱鏁幫級 <br>鍦╓indows騫沖彴涓嬶紝媯嫻嬪唴瀛樻硠婕忕殑宸ュ叿甯哥敤鐨勪竴鑸湁涓夌錛孧S C-Runtime Library鍐呭緩鐨勬嫻嬪姛鑳斤紱澶栨寕寮忕殑媯嫻嬪伐鍏鳳紝璇稿錛孭urify錛孊oundsChecker絳夛紱鍒╃敤Windows NT鑷甫鐨凱erformance Monitor銆傝繖涓夌宸ュ叿鍚勬湁浼樼己鐐癸紝MS C-Runtime Library铏界劧鍔熻兘涓婅緝涔嬪鎸傚紡鐨勫伐鍏瘋寮憋紝浣嗘槸瀹冩槸鍏嶈垂鐨勶紱Performance Monitor铏界劧鏃犳硶鏍囩ず鍑哄彂鐢熼棶棰樼殑浠g爜錛屼絾鏄畠鑳芥嫻嬪嚭闅愬紡鐨勫唴瀛樻硠婕忕殑瀛樺湪錛岃繖鏄叾浠栦袱綾誨伐鍏鋒棤鑳戒負鍔涚殑鍦版柟銆?<br>浠ヤ笅鎴戜滑璇︾粏璁ㄨ榪欎笁縐嶆嫻嬪伐鍏鳳細 <br>VC涓嬪唴瀛樻硠婕忕殑媯嫻嬫柟娉?<br>鐢∕FC寮鍙戠殑搴旂敤紼嬪簭錛屽湪DEBUG鐗堟ā寮忎笅緙栬瘧鍚庯紝閮戒細鑷姩鍔犲叆鍐呭瓨娉勬紡鐨勬嫻嬩唬鐮併傚湪紼嬪簭緇撴潫鍚庯紝濡傛灉鍙戠敓浜嗗唴瀛樻硠婕忥紝鍦―ebug紿楀彛涓細鏄劇ず鍑烘墍鏈夊彂鐢熸硠婕忕殑鍐呭瓨鍧楃殑淇℃伅錛屼互涓嬩袱琛屾樉紺轟簡涓鍧楄娉勬紡鐨勫唴瀛樺潡鐨勪俊鎭細 <br>E:\TestMemLeak\TestDlg.cpp(70)     : {59} normal block at 0x00881710, 200 bytes long. <br>Data: <abcdefghijklmnop>     61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 <br>絎竴琛屾樉紺鴻鍐呭瓨鍧楃敱TestDlg.cpp鏂囦歡錛岀70琛屼唬鐮佸垎閰嶏紝鍦板潃鍦?x00881710錛屽ぇ灝忎負200瀛楄妭錛寋59}鏄寚璋冪敤鍐呭瓨鍒嗛厤鍑芥暟鐨凴equest Order錛屽叧浜庡畠鐨勮緇嗕俊鎭彲浠ュ弬瑙丮SDN涓璤CrtSetBreakAlloc()鐨勫府鍔┿傜浜岃鏄劇ず璇ュ唴瀛樺潡鍓?6涓瓧鑺傜殑鍐呭錛屽皷鎷彿鍐呮槸浠SCII鏂瑰紡鏄劇ず錛屾帴鐫鐨勬槸浠?6榪涘埗鏂瑰紡鏄劇ず銆?<br>涓鑸ぇ瀹墮兘璇互涓鴻繖浜涘唴瀛樻硠婕忕殑媯嫻嬪姛鑳芥槸鐢盡FC鎻愪緵鐨勶紝鍏跺疄涓嶇劧銆侻FC鍙槸灝佽鍜屽埄鐢ㄤ簡MS C-Runtime Library鐨凞ebug Function銆傞潪MFC紼嬪簭涔熷彲浠ュ埄鐢∕S C-Runtime Library鐨凞ebug Function鍔犲叆鍐呭瓨娉勬紡鐨勬嫻嬪姛鑳姐侻S C-Runtime Library鍦ㄥ疄鐜癿alloc/free錛宻trdup絳夊嚱鏁版椂宸茬粡鍐呭緩浜嗗唴瀛樻硠婕忕殑媯嫻嬪姛鑳姐?<br>娉ㄦ剰瑙傚療涓涓嬬敱MFC Application Wizard鐢熸垚鐨勯」鐩紝鍦ㄦ瘡涓涓猚pp鏂囦歡鐨勫ご閮ㄩ兘鏈夎繖鏍蜂竴孌靛畯瀹氫箟錛?<br>#ifdef     _DEBUG <br>#define     new DEBUG_NEW <br>#undef     THIS_FILE <br>static     char THIS_FILE[] = __FILE__; <br>#endif <br>鏈変簡榪欐牱鐨勫畾涔夛紝鍦ㄧ紪璇慏EBUG鐗堟椂錛屽嚭鐜板湪榪欎釜cpp鏂囦歡涓殑鎵鏈塶ew閮借鏇挎崲鎴怐EBUG_NEW浜嗐傞偅涔圖EBUG_NEW鏄粈涔堝憿錛烡EBUG_NEW涔熸槸涓涓畯錛屼互涓嬫憳鑷猘fx.h錛?632琛?<br>#define     DEBUG_NEW new(THIS_FILE, __LINE__) <br>鎵浠ュ鏋滄湁榪欐牱涓琛屼唬鐮侊細 <br>char*     p = new char[200]; <br>緇忚繃瀹忔浛鎹㈠氨鍙樻垚浜嗭細 <br>char*     p = new( THIS_FILE, __LINE__)char[200]; <br>鏍規嵁C++鐨勬爣鍑嗭紝瀵逛簬浠ヤ笂鐨刵ew鐨勪嬌鐢ㄦ柟娉曪紝緙栬瘧鍣ㄤ細鍘繪壘榪欐牱瀹氫箟鐨刼perator new錛?<br>void*     operator new(size_t, LPCSTR, int) <br>鎴戜滑鍦╝fxmem.cpp 63琛屾壘鍒頒簡涓涓繖鏍風殑operator new 鐨勫疄鐜?<br>void*     AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine) <br>{ <br>    return     ::operator new(nSize, _NORMAL_BLOCK, lpszFileName, nLine); <br>} <br>void*     __cdecl operator new(size_t nSize, int nType, LPCSTR lpszFileName, int     nLine) <br>{ <br>    … <br>           pResult = _malloc_dbg(nSize, nType,     lpszFileName, nLine); <br>           if (pResult != NULL) <br>               return pResult; <br>    … <br>} <br>絎簩涓猳perator new鍑芥暟姣旇緝闀匡紝涓轟簡綆鍗曟湡闂達紝鎴戝彧鎽樺綍浜嗛儴鍒嗐傚緢鏄劇劧鏈鍚庣殑鍐呭瓨鍒嗛厤榪樻槸閫氳繃_malloc_dbg鍑芥暟瀹炵幇鐨勶紝榪欎釜鍑芥暟灞炰簬MS C-Runtime Library 鐨凞ebug Function銆傝繖涓嚱鏁頒笉浣嗚姹備紶鍏ュ唴瀛樼殑澶у皬錛屽彟澶栬繕鏈夋枃浠跺悕鍜岃鍙蜂袱涓弬鏁般傛枃浠跺悕鍜岃鍙峰氨鏄敤鏉ヨ褰曟嬈″垎閰嶆槸鐢卞摢涓孌典唬鐮侀犳垚鐨勩傚鏋滆繖鍧楀唴瀛樺湪紼嬪簭緇撴潫涔嬪墠娌℃湁琚噴鏀撅紝閭d箞榪欎簺淇℃伅灝變細杈撳嚭鍒癉ebug紿楀彛閲屻?<br>榪欓噷欏轟究鎻愪竴涓婽HIS_FILE錛宊_FILE鍜宊_LINE__銆俖_FILE__鍜宊_LINE__閮芥槸緙栬瘧鍣ㄥ畾涔夌殑瀹忋傚綋紕板埌__FILE__鏃訛紝緙栬瘧鍣ㄤ細鎶奯_FILE__鏇挎崲鎴愪竴涓瓧絎︿覆錛岃繖涓瓧絎︿覆灝辨槸褰撳墠鍦ㄧ紪璇戠殑鏂囦歡鐨勮礬寰勫悕銆傚綋紕板埌__LINE__鏃訛紝緙栬瘧鍣ㄤ細鎶奯_LINE__鏇挎崲鎴愪竴涓暟瀛楋紝榪欎釜鏁板瓧灝辨槸褰撳墠榪欒浠g爜鐨勮鍙楓傚湪DEBUG_NEW鐨勫畾涔変腑娌℃湁鐩存帴浣跨敤__FILE__錛岃屾槸鐢ㄤ簡THIS_FILE錛屽叾鐩殑鏄負浜嗗噺灝忕洰鏍囨枃浠剁殑澶у皬銆傚亣璁懼湪鏌愪釜cpp鏂囦歡涓湁100澶勪嬌鐢ㄤ簡new錛屽鏋滅洿鎺ヤ嬌鐢╛_FILE__錛岄偅緙栬瘧鍣ㄤ細浜х敓100涓父閲忓瓧絎︿覆錛岃繖100涓瓧絎︿覆閮芥槸榪欎釜cpp鏂囦歡鐨勮礬寰勫悕錛屾樉鐒跺崄鍒嗗啑浣欍傚鏋滀嬌鐢═HIS_FILE錛岀紪璇戝櫒鍙細浜х敓涓涓父閲忓瓧絎︿覆錛岄偅100澶刵ew鐨勮皟鐢ㄤ嬌鐢ㄧ殑閮芥槸鎸囧悜甯擱噺瀛楃涓茬殑鎸囬拡銆?<br>鍐嶆瑙傚療涓涓嬬敱MFC Application Wizard鐢熸垚鐨勯」鐩紝鎴戜滑浼氬彂鐜板湪cpp鏂囦歡涓彧瀵筺ew鍋氫簡鏄犲皠錛屽鏋滀綘鍦ㄧ▼搴忎腑鐩存帴浣跨敤malloc鍑芥暟鍒嗛厤鍐呭瓨錛岃皟鐢╩alloc鐨勬枃浠跺悕鍜岃鍙鋒槸涓嶄細琚褰曚笅鏉ョ殑銆傚鏋滆繖鍧楀唴瀛樺彂鐢熶簡娉勬紡錛孧S C-Runtime Library浠嶇劧鑳芥嫻嬪埌錛屼絾鏄綋杈撳嚭榪欏潡鍐呭瓨鍧楃殑淇℃伅錛屼笉浼氬寘鍚垎閰嶅畠鐨勭殑鏂囦歡鍚嶅拰琛屽彿銆?<br>瑕佸湪闈濵FC紼嬪簭涓墦寮鍐呭瓨娉勬紡鐨勬嫻嬪姛鑳介潪甯稿鏄擄紝浣犲彧瑕佸湪紼嬪簭鐨勫叆鍙e鍔犲叆浠ヤ笅鍑犺浠g爜錛?<br>int     tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); <br>tmpFlag     |= _CRTDBG_LEAK_CHECK_DF; <br>_CrtSetDbgFlag(     tmpFlag ); <br>榪欐牱錛屽湪紼嬪簭緇撴潫鐨勬椂鍊欙紝涔熷氨鏄痺inmain錛宮ain鎴杁llmain鍑芥暟榪斿洖涔嬪悗錛屽鏋滆繕鏈夊唴瀛樺潡娌℃湁閲婃斁錛屽畠浠殑淇℃伅浼氳鎵撳嵃鍒癉ebug紿楀彛閲屻?<br>濡傛灉浣犺瘯鐫鍒涘緩浜嗕竴涓潪MFC搴旂敤紼嬪簭錛岃屼笖鍦ㄧ▼搴忕殑鍏ュ彛澶勫姞鍏ヤ簡浠ヤ笂浠g爜錛屽茍涓旀晠鎰忓湪紼嬪簭涓笉閲婃斁鏌愪簺鍐呭瓨鍧楋紝浣犱細鍦―ebug紿楀彛閲岀湅鍒頒互涓嬬殑淇℃伅錛?<br>{47}     normal block at 0x00C91C90, 200 bytes long. <br>Data: <            > 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F <br>鍐呭瓨娉勬紡鐨勭‘媯嫻嬪埌浜嗭紝浣嗘槸鍜屼笂闈FC紼嬪簭鐨勪緥瀛愮浉姣旓紝緙哄皯浜嗘枃浠跺悕鍜岃鍙楓傚浜庝竴涓瘮杈冨ぇ鐨勭▼搴忥紝娌℃湁榪欎簺淇℃伅錛岃В鍐抽棶棰樺皢鍙樺緱鍗佸垎鍥伴毦銆?<br>涓轟簡鑳藉鐭ラ亾娉勬紡鐨勫唴瀛樺潡鏄湪鍝噷鍒嗛厤鐨勶紝浣犻渶瑕佸疄鐜扮被浼糓FC鐨勬槧灝勫姛鑳斤紝鎶妌ew錛宮aolloc絳夊嚱鏁版槧灝勫埌_malloc_dbg鍑芥暟涓娿傝繖閲屾垜涓嶅啀璧樿堪錛屼綘鍙互鍙傝僊FC鐨勬簮浠g爜銆?<br>鐢變簬Debug Function瀹炵幇鍦∕S C-RuntimeLibrary涓紝鎵浠ュ畠鍙兘媯嫻嬪埌鍫嗗唴瀛樼殑娉勬紡錛岃屼笖鍙檺浜巑alloc錛宺ealloc鎴杝trdup絳夊垎閰嶇殑鍐呭瓨錛岃岄偅浜涚郴緇熻祫婧愶紝姣斿HANDLE錛孏DI Object錛屾垨鏄笉閫氳繃C-Runtime Library鍒嗛厤鐨勫唴瀛橈紝姣斿VARIANT錛孊STR鐨勬硠婕忥紝瀹冩槸鏃犳硶媯嫻嬪埌鐨勶紝榪欐槸榪欑媯嫻嬫硶鐨勪竴涓噸澶х殑灞闄愭с傚彟澶栵紝涓轟簡鑳借褰曞唴瀛樺潡鏄湪鍝噷鍒嗛厤鐨勶紝婧愪唬鐮佸繀欏葷浉搴旂殑閰嶅悎錛岃繖鍦ㄨ皟璇曚竴浜涜佺殑紼嬪簭闈炲父楹葷儲錛屾瘯绔熶慨鏀規簮浠g爜涓嶆槸涓浠剁渷蹇冪殑浜嬶紝榪欐槸榪欑媯嫻嬫硶鐨勫彟涓涓眬闄愭с?<br>瀵逛簬寮鍙戜竴涓ぇ鍨嬬殑紼嬪簭錛孧S C-Runtime Library鎻愪緵鐨勬嫻嬪姛鑳芥槸榪滆繙涓嶅鐨勩傛帴涓嬫潵鎴戜滑灝辯湅鐪嬪鎸傚紡鐨勬嫻嬪伐鍏楓傛垜鐢ㄧ殑姣旇緝澶氱殑鏄疊oundsChecker錛屼竴鍒欏洜涓哄畠鐨勫姛鑳芥瘮杈冨叏闈紝鏇撮噸瑕佺殑鏄畠鐨勭ǔ瀹氭с傝繖綾誨伐鍏峰鏋滀笉紼沖畾錛屽弽鑰屼細蹇欓噷娣諱貢銆傚埌搴曟槸鍑鴻嚜榧庨紟澶у悕鐨凬uMega錛屾垜鐢ㄤ笅鏉ュ熀鏈笂娌℃湁浠涔堝ぇ闂銆?<br> <img src ="http://www.shnenglu.com/SpringSnow/aggbug/65740.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/SpringSnow/" target="_blank">Sandy</a> 2008-11-02 10:54 <a href="http://www.shnenglu.com/SpringSnow/articles/65740.html#Feedback" target="_blank" style="text-decoration:none;">鍙戣〃璇勮</a></div>]]></description></item><item><title>杞細鍐呭瓨娉勯湶媯嫻?http://www.shnenglu.com/SpringSnow/articles/65739.htmlSandySandySun, 02 Nov 2008 02:53:00 GMThttp://www.shnenglu.com/SpringSnow/articles/65739.htmlhttp://www.shnenglu.com/SpringSnow/comments/65739.htmlhttp://www.shnenglu.com/SpringSnow/articles/65739.html#Feedback0http://www.shnenglu.com/SpringSnow/comments/commentRss/65739.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/65739.html
http://www.shnenglu.com/Ipedo/archive/2005/10/27/867.aspx

 c錛嬶紜涓嫻嬪唴瀛樻硠婕忓彲浠ュ紩鍏ョ郴緇熷畾涔夌殑瀹忔潵鏌ョ湅錛屽唴瀛樺湪鍝釜浣嶇疆娉勬紡

鏂囦歡寮濮嬪鍔犲叆涓嬪垪瀹氫箟
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

紼嬪簭閫鍑烘椂鍔犲叆浠ヤ笅鍑芥暟錛?br>
_CrtDumpMemoryLeaks();

濡傛灉鏈夋硠婕忎細鏄劇ず
e:\myproject\mltithrd.14\mltithrd.cpp(95) : {68} client block at 0x00372550, subtype c0, 144 bytes long.
a CMultiDocTemplate object at $00372550, 144 bytes long


Sandy 2008-11-02 10:53 鍙戣〃璇勮
]]>
杞細媯嫻嬪唴瀛樻硠闇茬殑宸ュ叿錛歞ebugnewhttp://www.shnenglu.com/SpringSnow/articles/65738.htmlSandySandySun, 02 Nov 2008 02:52:00 GMThttp://www.shnenglu.com/SpringSnow/articles/65738.htmlhttp://www.shnenglu.com/SpringSnow/comments/65738.htmlhttp://www.shnenglu.com/SpringSnow/articles/65738.html#Feedback0http://www.shnenglu.com/SpringSnow/comments/commentRss/65738.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/65738.html 

媯嫻嬪唴瀛樻硠闇茬殑宸ュ叿錛歞ebugnew
http://dev.csdn.net/article/58/58407.shtm

緗戜笂鏈変竴涓祦浼犵敋騫跨殑媯嫻嬪唴瀛樻硠闇茬殑宸ュ叿錛歞ebugnew(debugnew.h/debugnew.cpp)
鐢ㄦ硶寰堢畝鍗曪紝鎶奷ebugnew.cpp鏀懼湪欏圭洰閲屼竴璧風紪璇戯紝闇瑕佹嫻嬬殑鏂囦歡鎶奷ebugnew.h宓屽湪鏂囦歡鐨勬渶鍓嶉潰銆?br>
涓烘柟渚夸嬌鐢紝瀵規簮浠g爜鍋氫簡涓浜涘皬鐨勬敼鍔ㄣ?br>
涓嬮潰鏄竴浜涚畝鍗曠殑璇存槑錛?/p>

1銆乶ew 鐨勯噸杞?/font>
void* operator new (size_t size, const char* file, int line)錛涖銆銆銆銆銆銆銆鈶?br>void* operator new [] (size_t size, const char*  file, int line)錛涖銆銆銆銆銆鈶?/p>

鍦ㄩ渶瑕佹嫻嬬殑鏂囦歡閲岋紝閲嶅畾涔塶ew
#define new new(__FILE__, __LINE__)

閫犳垚鐨勭粨鏋滐細
ClassName *p = new ClassName; => ClassName *p = new(__FILE__, __LINE__) ClassName;
// 瀹為檯浼氳皟鐢╲oid* operator new (size_t size, const char* file, int line)錛?/p>

ClassName **pp = new classname[count]; => ClassName **pp = new(__FILE__, __LINE__) ClassName[count];
// 瀹為檯浼氳皟鐢╲oid* operator new [] (size_t size, const char*  file, int line)錛?/p>

榪欏叾瀹炴槸鍒╃敤浜唒lacement new鐨勮娉曪紝閫氳繃涓涓畝鍗曠殑瀹忥紝灝卞彲浠ユ妸鏅氱殑new鎿嶄綔瀵瑰簲鍒扮浉搴旂殑閲嶈澆( 鈶?鈶?)涓婂幓銆?/p>

2銆乨elete 鐨勯噸杞?/strong>
void operator delete (void* p, const char* file, int line);                   鈶?br>void operator delete [] (void* p, const char* file, int line);                鈶?br>void operator delete (void* p);                                               鈶?br>void operator delete [] (void* p);                                            鈶?/p>

鍥犱負娌℃湁綾諱技浜巔lacement new鐨勮娉曪紝鎵浠ュ氨涓嶈兘鐢ㄤ竴涓畯鏉ユ浛鎹㈡浛鎹elete浜嗐傝璋冪敤甯︽湁鏇村淇℃伅鐨刣elete鎿嶄綔絎︼紝鍙兘淇敼婧愪唬鐮佷簡銆?br>delete p; => delete ( p, __FILE__, __LINE__ );
delete []pp; => delete [] ( pp, __FILE__, __LINE__ );
浣嗚繖涓伐浣滃緢鐑︾悙錛屽鏋滃茍涓嶉渶瑕佸浣欑殑淇℃伅鐨勮瘽錛岀畝鍗曞湴閲嶈澆delete( 鈶?鈶?)灝卞彲浠ヤ簡銆?/p>

3銆佹嫻嬪拰緇熻
紼嬪簭寮濮嬫椂錛屽湪debugnew.cpp涓細鍒涘緩涓涓狣ebugNewTracer瀵硅薄
鍦ㄩ噸杞界殑new鎿嶄綔絎? 鈶?鈶?)涓紝姣忎竴嬈″唴瀛樺垎閰嶉兘浼氳璁板綍錛岃屽湪delete( 鈶?鈶?鈶?鈶?)涓垯浼氬垹闄ょ浉搴旂殑璁板綍銆?br>褰撶▼搴忕粨鏉燂紝DebugNewTracer瀵硅薄琚攢姣侊紝瀹冪殑鏋愭瀯鍑芥暟浼歞ump鍓╀綑鐨勮褰曪紝榪欏氨鏄硠闇茬殑鍐呭瓨浜嗐?/p>

鍦ㄥ師鏈変唬鐮佺殑鍩虹涓婏紝澧炲姞浜嗚褰晄ize鐨勫姛鑳斤紝榪欐牱鍙互鍦ㄦ瘡嬈ew鍜宒elete鏃訛紝鐪嬪埌瀹為檯鍗犵敤鐨勫唴瀛樸傛墍鏈変俊鎭彲浠ump鍑烘潵錛屼篃鍙互鍐欏叆log銆?br>

5銆佹簮浠g爜

********************************************************
debugnew.h:

/*
 filename: debugnew.h
 
 This code is based on code retrieved from a web site. The
 author was not identified, so thanks go to anonymous.

 This is used to substitute a version of the new operator that
 can be used for debugging memory leaks. To use it:
 
 - In any (all?) code files #include debugnew.h. Make sure all
  system files (i.e. those in <>'s) are #included before
  debugnew.h, and that any header files for your own code
  are #included after debugnew.h. The reason is that some
  system files refer to ::new, and this will not compile
  if debugnew is in effect. You may still have problems
  if any of your own code refers to ::new, or if any
  of your own files #include system files that use ::new
  and which have not already been #included before
  debugnew.h.
 - Add debugnew.cpp to the CodeWarrior project or compile
  it into your Linux executable. If debugnew.cpp is in the
  project, then debugnew.h must be #included in at least
  one source file
*/

#ifndef __DEBUGNEW_H__
#define __DEBUGNEW_H__

#include <map>

#define LOG_FILE

#if defined(LOG_FILE)
#define LOG_FILE_NAME "./debugnew.log"
#endif

void* operator new (std::size_t size, const char* file, int line);
void operator delete (void* p, const char* name, int line);
void* operator new [] (std::size_t size, const char* file, int line);
void operator delete [] (void* p, const char* name, int line);

class DebugNewTracer  {
private:
 
 class Entry  {
 public:
  Entry (char const* file, int line) : _file (file), _line (line) {}
  Entry (char const* file, int line, int size) : _file (file), _line (line), _size (size) {}
  Entry () : _file (0), _line (0), _size (0) {}
  const char* File () const { return _file; }
  int Line () const { return _line; }
  size_t Size () const { return _size; }
 private:
  char const* _file;
  int _line;
  size_t _size;
 };

 class Lock {
 public:
  Lock (DebugNewTracer & DebugNewTracer) : _DebugNewTracer (DebugNewTracer) {
   _DebugNewTracer.lock ();
  }
  ~Lock () {
   _DebugNewTracer.unlock ();
  }
 private:
  DebugNewTracer & _DebugNewTracer;
 };
 typedef std::map<void*, Entry>::iterator iterator;
 friend class Lock;
 public:
 DebugNewTracer ();
 ~DebugNewTracer ();
 void Add (void* p, const char* file, int line);
 void Add (void* p, const char* file, int line, size_t size);
 void Remove (void* p);
 void Dump ();

 static bool Ready;

 private:
 void lock () { _lockCount++; }
 void unlock () { _lockCount--; }

 private:

 std::map<void*, Entry> _map;
 int _lockCount;
 size_t _totalsize;
#if defined(LOG_FILE)
 FILE* _logfp;
#endif
 };

 // The file that implements class DebugNewTracer
 // does NOT want the word "new" expanded.
 // The object DebugNewTrace is defined in that
 // implementation file but only declared in any other file.
#ifdef DEBUGNEW_CPP
DebugNewTracer DebugNewTrace;
#else
#define new new(__FILE__, __LINE__)
extern DebugNewTracer DebugNewTrace;
#endif

#endif//#ifndef __DEBUGNEW_H__


********************************************************
debugnew.cpp:

/*
 filename: debugnew.cpp

 This is used to substitute a version of the new operator that
 can be used for debugging memory leaks. In any (all?) code
 files #include debugnew.h. Add debugnew.cpp to the project.
*/

#include <iostream>
#include <map>

using namespace std;

 // This disables macro expansion of "new".
 // This statement should only appear in this file.
#define DEBUGNEW_CPP

#include "debugnew.h"

DebugNewTracer::DebugNewTracer () : _lockCount (0)
{
  // Once this object is constructed all calls to
  // new should be traced.

 Ready = true;
 _totalsize = 0;
#if defined(LOG_FILE)
 if( (_logfp=fopen(LOG_FILE_NAME,"wt")) == NULL )
 {
  printf(" Error! file: debugnew.log can not open@!\n");
  return;
 } 
 fprintf(_logfp,"new, delete list:\n");
 fflush(_logfp);
#endif
 
}
        
void DebugNewTracer::Add (void* p, const char* file, int line)
{
  // Tracing must not be done a second time
  // while it is already
  // in the middle of executing
 if (_lockCount > 0)
  return;

   // Tracing must be disabled while the map
   // is in use in case it calls new.
 DebugNewTracer::Lock lock (*this);
 _map [p] = Entry (file, line);
}

void DebugNewTracer::Add (void* p, const char* file, int line, size_t size)
{
 // Tracing must not be done a second time
 // while it is already
 // in the middle of executing
 if (_lockCount > 0)
  return;

  // Tracing must be disabled while the map
  // is in use in case it calls new.
 DebugNewTracer::Lock lock (*this);
#if 1
 //´Óȫ·¾¶ÖÐÌáÈ¡ÎļþÃû
 //linuxϵÄgcc,__FILE__½ö½ö°üÀ¨ÎļþÃû£¬windowsϵÄvc,__FILE__°üÀ¨È«Â·¾¶,ËùÒÔÓÐÕâÑùµÄ´¦Àí
 file = strrchr(file,'\\')== NULL?file:strrchr(file,'\\')+1;
#endif
 _map [p] = Entry (file, line, size);
 _totalsize += size;
#if defined(LOG_FILE)
 fprintf(_logfp,"*N p = 0x%08x, size = %6d,  %-22s, Line: %4d.  totalsize =%8d\n", p, size, file, line, _totalsize);
 fflush(_logfp);
#endif
}


void DebugNewTracer::Remove (void* p)
{
 // Tracing must not be done a second time
 // while it is already
 // in the middle of executing
 if (_lockCount > 0)
  return;

  // Tracing must be disabled while the map
  // is in use in case it calls new.
 DebugNewTracer::Lock lock (*this);

 iterator it = _map.find (p);

 if (it != _map.end ())
 {
  size_t size = (*it).second.Size();
  _totalsize -= size;
#if defined(LOG_FILE)
  fprintf(_logfp,"#D p = 0x%08x, size = %6u.%39stotalsize =%8d\n", p, size, "-----------------------------------  ", _totalsize );
  fflush(_logfp);
#endif
  _map.erase (it);
 }
 else
 {
#if defined(LOG_FILE)
  fprintf(_logfp,"#D p = 0x%08x. error point!!!\n", p );
  fflush(_logfp);
#endif
 }
}

DebugNewTracer::~DebugNewTracer ()
{
 // Trace must not be called if Dump indirectly
 // invokes new, so it must be disabled before
 // Dump is called. After this destructor executes
 // any other global objects that get destructed
 // should not do any tracing.
 Ready = false;
 Dump ();
#if defined(LOG_FILE)
 fclose(_logfp);
#endif
}

// If some global object is destructed after DebugNewTracer
// and if that object calls new, it should not trace that
// call to new.
void DebugNewTracer::Dump ()
{
 if (_map.size () != 0)
 {
  std::cout << _map.size () << " memory leaks detected\n";
#if defined(LOG_FILE)
  fprintf(_logfp, "\n\n***%d memory leaks detected\n", _map.size ());
  fflush(_logfp);
#endif
  for (iterator it = _map.begin (); it != _map.end (); ++it)
  {
   char const * file = it->second.File ();
   int line = it->second.Line ();
   int size = it->second.Size ();
   std::cout << file << ", "  << line << std::endl;
#if defined(LOG_FILE)
   fprintf(_logfp,"%s, %d, size=%d\n", file, line, size);
   fflush(_logfp);
#endif
  }
 }
 else
 {
  std::cout << "no leaks detected\n";
#if defined(LOG_FILE)
  fprintf(_logfp,"no leaks detected\n");
  fflush(_logfp);
#endif
 }

}

// If some global object is constructed before DebugNewTracer
// and if that object calls new, it should not trace that
// call to new.
bool DebugNewTracer::Ready = false;

void* operator new (size_t size, const char* file, int line)
{
 void * p = malloc (size);
 if (DebugNewTracer::Ready)
  DebugNewTrace.Add (p, file, line, size);
 return p;
}

void operator delete (void* p, const char* file, int line)
{
 file = 0; // avoid a warning about argument not used in function
 line = 0; // avoid a warning about argument not used in function
 
 if (DebugNewTracer::Ready)
  DebugNewTrace.Remove (p);
 free (p);
}
        
void* operator new [] (size_t size, const char*  file, int line)
{
 void * p = malloc (size);
 if (DebugNewTracer::Ready)
  DebugNewTrace.Add (p, file, line, size);
 return p;
}

void operator delete [] (void* p, const char* file, int line)
{
 file = 0; // avoid a warning about argument not used in function
 line = 0; // avoid a warning about argument not used in function
 
 if (DebugNewTracer::Ready)
   DebugNewTrace.Remove (p);
 free (p);
}
        
void* operator new (size_t size)
{
 void * p = malloc (size);
 // When uncommented these lines cause entries in the map for calls to new
 // that were not altered to the debugnew version. These are likely calls
 // in library functions and the presence in the dump of these entries
 // is usually misleading.
 // if (DebugNewTracer::Ready)
 //   DebugNewTrace.Add (p, "?", 0);
 return p;
}
 
void operator delete (void* p)
{
 if (DebugNewTracer::Ready)
  DebugNewTrace.Remove (p);
 free (p);
}

//add by yugang
void operator delete [] (void* p)
{
 if (DebugNewTracer::Ready)
  DebugNewTrace.Remove (p);
 free (p);
}



Sandy 2008-11-02 10:52 鍙戣〃璇勮
]]>
铏氱戶鎵夸笌铏氬熀綾葷殑鏈川 http://www.shnenglu.com/SpringSnow/articles/64209.htmlSandySandyThu, 16 Oct 2008 14:19:00 GMThttp://www.shnenglu.com/SpringSnow/articles/64209.htmlhttp://www.shnenglu.com/SpringSnow/comments/64209.htmlhttp://www.shnenglu.com/SpringSnow/articles/64209.html#Feedback0http://www.shnenglu.com/SpringSnow/comments/commentRss/64209.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/64209.html    铏氱戶鎵垮拰铏氬熀綾葷殑瀹氫箟鏄潪甯哥殑綆鍗曠殑錛屽悓鏃朵篃鏄潪甯稿鏄撳垽鏂竴涓戶鎵挎槸鍚︽槸铏氱戶鎵?br>鐨勶紝铏界劧榪欎袱涓蹇電殑瀹氫箟鏄潪甯哥殑綆鍗曟槑紜殑錛屼絾鏄湪C++璇█涓櫄緇ф壙浣滀負涓涓瘮杈冪敓
鍍葷殑浣嗘槸鍙堟槸緇濆蹇呰鐨勭粍鎴愰儴浠借屽瓨鍦ㄧ潃錛屽茍涓斿叾琛屼負鍜屾ā鍨嬪潎琛ㄧ幇鍑哄拰涓鑸殑緇ф壙浣撶郴
涔嬮棿鐨勫法澶х殑宸紓錛堝寘鎷闂ц兘涓婄殑宸紓錛夛紝鐜板湪鎴戜滑灝辨潵褰誨簳鐨勪粠璇█銆佹ā鍨嬨佹ц兘鍜?br>搴旂敤絳夊涓柟闈㈠铏氱戶鎵垮拰铏氬熀綾昏繘琛岀爺絀躲?br>    棣栧厛榪樻槸鍏堢粰鍑鴻櫄緇ф壙鍜岃櫄鍩虹被鐨勫畾涔夈?br>    铏氱戶鎵匡細鍦ㄧ戶鎵垮畾涔変腑鍖呭惈浜唙irtual鍏抽敭瀛楃殑緇ф壙鍏崇郴錛?br>    铏氬熀綾伙細鍦ㄨ櫄緇ф壙浣撶郴涓殑閫氳繃virtual緇ф壙鑰屾潵鐨勫熀綾伙紝闇瑕佹敞鎰忕殑鏄細
            struct CSubClass : public virtual CBase {}; 鍏朵腑CBase縐頒箣涓篊SubClass
            鐨勮櫄鍩虹被錛岃屼笉鏄CBase灝辨槸涓櫄鍩虹被錛屽洜涓篊Base榪樺彲浠ヤ笉涓嶆槸铏氱戶鎵夸綋緋?br>            涓殑鍩虹被銆?br>    鏈変簡涓婇潰鐨勫畾涔夊悗錛屽氨鍙互寮濮嬭櫄緇ф壙鍜岃櫄鍩虹被鐨勬湰璐ㄧ爺絀朵簡錛屼笅闈㈡寜鐓ц娉曘佽涔夈?br>妯″瀷銆佹ц兘鍜屽簲鐢ㄤ簲涓柟闈㈣繘琛屽叏闈㈢殑鎻忚堪銆?br>
    1. 璇硶
       璇硶鏈夎璦鐨勬湰韜殑瀹氫箟鎵鍐沖畾錛屾諱綋涓婃潵璇撮潪甯哥殑綆鍗曪紝濡備笅錛?br>           struct CSubClass : public virtual CBaseClass {};
       鍏朵腑鍙互閲囩敤public銆乸rotected銆乸rivate涓夌涓嶅悓鐨勭戶鎵垮叧閿瓧榪涜淇グ錛屽彧瑕?br>       紜繚鍖呭惈virtual灝卞彲浠ヤ簡錛岃繖鏍蜂竴鏉ュ氨褰㈡垚浜嗚櫄緇ф壙浣撶郴錛屽悓鏃禖BaseClass灝辨垚涓?br>       浜咰SubClass鐨勮櫄鍩虹被浜嗐?br>       鍏跺疄騫舵病鏈夐偅涔堢殑綆鍗曪紝濡傛灉鍑虹幇铏氱戶鎵夸綋緋葷殑榪涗竴姝ョ戶鎵夸細鍑虹幇浠涔堟牱鐨勭姸鍐靛憿錛?br>       濡備笅鎵紺猴細
            /*
             * 甯︽湁鏁版嵁鎴愬憳鐨勫熀綾?br>             */
            struct CBaseClass1
            {
                CBaseClass1( size_t i ) : m_val( i ) {}
            
                size_t m_val;
            };
            /*
             * 铏氭嫙緇ф壙浣撶郴
             */
            struct CSubClassV1 : public virtual CBaseClass1
            {
                CSubClassV1( size_t i ) : CBaseClass1( i ) {}
            };           
            struct CSubClassV2 : public virtual CBaseClass1
            {
                CSubClassV2( size_t i ) : CBaseClass1( i ) {}
            };           
            struct CDiamondClass1 : public CSubClassV1, public CSubClassV2
            {
                CDiamondClass1( size_t i ) : CBaseClass1( i ), CSubClassV1( i ), CSubClassV2( i ) {}
            };           
            struct CDiamondSubClass1 : public CDiamondClass1
            {
                CDiamondSubClass1( size_t i ) : CBaseClass1( i ), CDiamondClass1( i ) {}
            };
       娉ㄦ剰涓婇潰浠g爜涓殑CDiamondClass1鍜孋DiamondSubClass1涓や釜綾葷殑鏋勯犲嚱鏁板垵濮嬪寲鍒?br>       琛ㄤ腑鐨勫唴瀹廣傚彲浠ュ彂鐜板叾涓潎鍖呭惈浜嗚櫄鍩虹被CBaseClass1鐨勫垵濮嬪寲宸ヤ綔錛屽鏋滄病鏈夎繖
       涓垵濮嬪寲璇彞灝變細瀵艱嚧緙栬瘧鏃墮敊璇紝涓轟粈涔堜細榪欐牱鍛紵涓鑸儏鍐典笅涓嶆槸鍙鍦?br>       CSubClassV1鍜孋SubClassV2涓寘鍚垵濮嬪寲灝卞彲浠ヤ簡涔堬紵瑕佽В閲婅闂蹇呴』瑕佹槑鐧借櫄
       緇ф壙鐨勮涔夌壒寰侊紝鎵浠ュ弬鐪嬩笅闈㈣涔夐儴鍒嗙殑瑙i噴銆?br>      
    2. 璇箟
       浠庤涔変笂鏉ヨ浠涔堟槸铏氱戶鎵垮拰铏氬熀綾誨憿錛熶笂闈粎浠呮槸浠庡浣曞湪C++璇█涓功鍐欏悎娉曠殑
       铏氱戶鎵跨被瀹氫箟鑰屽凡銆傞鍏堟潵浜嗚В涓涓媣irtual榪欎釜鍏抽敭瀛楀湪C++涓殑鍏叡鍚箟錛屽湪C++
       璇█涓粎浠呮湁涓や釜鍦版柟鍙互浣跨敤virtual榪欎釜鍏抽敭瀛楋紝涓涓氨鏄被鎴愬憳铏氬嚱鏁板拰榪欓噷
       鎵璁ㄨ鐨勮櫄緇ф壙銆備笉瑕佺湅榪欎袱縐嶅簲鐢ㄥ満鍚堝ソ鍍忔病浠涔堝叧緋伙紝鍏跺疄浠栦滑鍦ㄨ儗鏅涔変笂
       鍏鋒湁virtual榪欎釜璇嶆墍浠h〃鐨勫叡鍚岀殑鍚箟錛屾墍浠ユ墠浼氬湪榪欎袱縐嶅満鍚堜嬌鐢ㄧ浉鍚岀殑鍏抽敭瀛椼?br>       閭d箞virtual榪欎釜璇嶇殑鍚箟鏄粈涔堝憿錛?br>       virtual鍦ㄣ婄編鍥戒紶緇熻瘝鍏竅鍙岃В]銆嬩腑鏄繖鏍峰畾涔夌殑錛?br>           adj.錛堝艦瀹硅瘝錛?br>           1. Existing or resulting in essence or effect though not in actual
              fact, form, or name:
              瀹炶川涓婄殑錛屽疄闄呬笂鐨勶細铏界劧娌℃湁瀹為檯鐨勪簨瀹炪佸艦寮忔垨鍚嶄箟錛屼絾鍦ㄥ疄闄呬笂鎴栨晥
              鏋滀笂瀛樺湪鎴栦駭鐢熺殑錛?br>           2. Existing in the mind, especially as a product of the imagination.
              Used in literary criticism of text.
              铏氱殑錛屽唴蹇冪殑錛氬湪澶磋剳涓瓨鍦ㄧ殑錛屽挨鎸囨剰鎯崇殑浜х墿銆傜敤浜庢枃瀛︽壒璇勪腑銆?br>       鎴戜滑閲囩敤絎竴涓畾涔夛紝涔熷氨鏄琚玽irtual鎵淇グ鐨勪簨鐗╂垨鐜拌薄鍦ㄦ湰璐ㄤ笂鏄瓨鍦ㄧ殑錛?br>       浣嗘槸娌℃湁鐩磋鐨勫艦寮忚〃鐜幫紝鏃犳硶鐩存帴鎻忚堪鎴栧畾涔夛紝闇瑕侀氳繃鍏朵粬鐨勯棿鎺ユ柟寮忔垨鎵嬫
       鎵嶈兘澶熶綋鐜板嚭鍏跺疄闄呬笂鐨勬晥鏋溿?br>       閭d箞鍦–++涓氨鏄噰鐢ㄤ簡榪欎釜璇嶆剰錛屼笉鍙互鍦ㄨ璦妯″瀷涓洿鎺ヨ皟鐢ㄦ垨浣撶幇鐨勶紝浣嗘槸紜?br>       瀹炴槸瀛樺湪鍙互琚棿鎺ョ殑鏂瑰紡榪涜璋冪敤鎴栦綋鐜扮殑銆傛瘮濡傦細铏氬嚱鏁板繀欏昏閫氳繃涓縐嶉棿鎺ョ殑
       榪愯鏃訛紙鑰屼笉鏄紪璇戞椂錛夋満鍒舵墠鑳藉嬋媧伙紙璋冪敤錛夌殑鍑芥暟錛岃岃櫄緇ф壙涔熸槸蹇呴』鍦ㄨ繍琛?br>       鏃舵墠鑳藉榪涜瀹氫綅璁塊棶鐨勪竴縐嶄綋鍒躲傚瓨鍦紝浣嗛棿鎺ャ傚叾涓叧閿氨鍦ㄤ簬瀛樺湪銆侀棿鎺ュ拰鍏?br>       浜繖涓夌鐗瑰緛銆?br>       瀵逛簬铏氬嚱鏁拌岃█錛岃繖涓変釜鐗瑰緛鏄緢濂界悊瑙g殑錛岄棿鎺ユц〃鏄庝簡浠栧繀欏誨湪榪愯鏃舵牴鎹疄闄?br>       鐨勫璞℃潵瀹屾垚鍑芥暟瀵誨潃錛屽叡浜ц〃璞″湪鍩虹被浼氬叡浜瀛愮被閲嶈澆鍚庣殑铏氬嚱鏁幫紝鍏跺疄鎸囧悜
       鐩稿悓鐨勫嚱鏁板叆鍙c?br>       瀵逛簬铏氱戶鎵胯岃█錛岃繖涓変釜鐗瑰緛濡備綍鐞嗚В鍛紵瀛樺湪鍗寵〃紺鴻櫄緇ф壙浣撶郴鍜岃櫄鍩虹被紜疄瀛樺湪錛?br>       闂存帴鎬ц〃鏄庝簡鍦ㄨ闂櫄鍩虹被鐨勬垚鍛樻椂鍚屾牱涔熷繀欏婚氳繃鏌愮闂存帴鏈哄埗鏉ュ畬鎴愶紙涓嬮潰妯″瀷
       涓細璁插埌錛夛紝鍏變韓鎬ц〃璞″湪铏氬熀綾諱細鍦ㄨ櫄緇ф壙浣撶郴涓鍏變韓錛岃屼笉浼氬嚭鐜板浠芥嫹璐濄?br>       閭g幇鍦ㄥ彲浠ヨВ閲婅娉曞皬鑺備腑鐣欎笅鏉ョ殑閭d釜闂浜嗭紝“涓轟粈涔堜竴鏃﹀嚭鐜頒簡铏氬熀綾伙紝灝卞繀
       欏誨湪娌℃湁涓涓戶鎵跨被涓兘蹇呴』鍖呭惈铏氬熀綾葷殑鍒濆鍖栬鍙?#8221;銆傜敱涓婇潰鐨勫垎鏋愬彲浠ョ煡閬擄紝
       铏氬熀綾繪槸琚叡浜殑錛屼篃灝辨槸鍦ㄧ戶鎵夸綋緋諱腑鏃犺琚戶鎵垮灝戞錛屽璞″唴瀛樻ā鍨嬩腑鍧囧彧浼?br>       鍑虹幇涓涓櫄鍩虹被鐨勫瓙瀵硅薄錛堣繖鍜屽緇ф壙鏄畬鍏ㄤ笉鍚岀殑錛夛紝榪欐牱涓鏉ユ棦鐒舵槸鍏變韓鐨勯偅涔?br>       姣忎竴涓瓙綾婚兘涓嶄細鐙崰錛屼絾鏄昏繕鏄繀欏昏鏈変竴涓被鏉ュ畬鎴愬熀綾葷殑鍒濆鍖栬繃紼嬶紙鍥犱負
       鎵鏈夌殑瀵硅薄閮藉繀欏昏鍒濆鍖栵紝鍝曟槸榛樿鐨勶級錛屽悓鏃惰繕涓嶈兘澶熼噸澶嶈繘琛屽垵濮嬪寲錛岄偅鍒?br>       搴曡皝搴旇璐熻矗瀹屾垚鍒濆鍖栧憿錛烠++鏍囧噯涓紙涔熸槸寰堣嚜鐒剁殑錛夐夋嫨鍦ㄦ瘡涓嬈$戶鎵垮瓙綾諱腑
       閮藉繀欏諱功鍐欏垵濮嬪寲璇彞錛堝洜涓烘瘡涓嬈$戶鎵垮瓙綾誨彲鑳介兘浼氱敤鏉ュ畾涔夊璞★級錛岃屽湪鏈涓嬪眰
       緇ф壙瀛愮被涓疄闄呮墽琛屽垵濮嬪寲榪囩▼銆傛墍浠ヤ笂闈㈠湪姣忎竴涓戶鎵跨被涓兘瑕佷功鍐欏垵濮嬪寲璇彞錛?br>       浣嗘槸鍦ㄥ垱寤哄璞℃椂錛岃屼粎浠呬細鍦ㄥ垱寤哄璞$敤鐨勭被鏋勯犲嚱鏁頒腑瀹為檯鐨勬墽琛屽垵濮嬪寲璇彞錛?br>       鍏朵粬鐨勫垵濮嬪寲璇彞閮戒細琚帇鍒朵笉璋冪敤銆?br>      
    3. 妯″瀷
       涓轟簡瀹炵幇涓婇潰鎵璇寸殑涓夌璇箟鍚箟錛屽湪鑰冭檻瀵硅薄鐨勫疄鐜版ā鍨嬶紙涔熷氨鏄唴瀛樻ā鍨嬶級鏃跺氨
       寰堣嚜鐒朵簡銆傚湪C++涓璞″疄闄呬笂灝辨槸涓涓繛緇殑鍦板潃絀洪棿鐨勮涔変唬琛紝鎴戜滑鏉ュ垎鏋愯櫄
       緇ф壙涓嬬殑鍐呭瓨妯″瀷銆?br>       3.1. 瀛樺湪
           涔熷氨鏄鍦ㄥ璞″唴瀛樹腑蹇呴』瑕佸寘鍚櫄鍩虹被鐨勫畬鏁村瓙瀵硅薄錛屼互渚胯兘澶熷畬鎴愰氳繃鍦板潃
           瀹屾垚瀵硅薄鐨勬爣璇嗐傞偅涔堣嚦浜庤櫄鍩虹被鐨勫瓙瀵硅薄浼氬瓨鏀懼湪瀵硅薄鐨勯偅涓綅緗紙澶淬佷腑闂淬?br>           灝鵑儴錛夊垯鐢卞悇涓紪璇戝櫒閫夋嫨錛屾病鏈夊樊鍒傦紙鍦╒C8涓棤璁鴻櫄鍩虹被琚0鏄庡湪浠涔堜綅緗紝
           铏氬熀綾葷殑瀛愬璞¢兘浼氳鏀劇疆鍦ㄥ璞″唴瀛樼殑灝鵑儴錛?br>       3.2. 闂存帴
           闂存帴鎬ц〃鏄庝簡鍦ㄧ洿鎺ヨ櫄鍩烘壙瀛愮被涓竴瀹氬寘鍚簡鏌愮鎸囬拡錛堝亸縐繪垨琛ㄦ牸錛夋潵瀹屾垚閫?br>           榪囧瓙綾昏闂櫄鍩虹被瀛愬璞★紙鎴栨垚鍛橈級鐨勯棿鎺ユ墜孌碉紙鍥犱負铏氬熀綾誨瓙瀵硅薄鏄叡浜殑錛?br>           娌℃湁紜畾鍏崇郴錛夛紝鑷充簬閲囩敤浣曠鎵嬫鐢辯紪璇戝櫒閫夋嫨銆傦紙鍦╒C8涓湪瀛愮被涓斁緗簡
           涓涓櫄鍩虹被鎸囬拡vbc錛岃鎸囬拡鎸囧悜铏氬嚱鏁拌〃涓殑涓涓猻lot錛岃slot涓瓨鏀懼垯铏氬熀
           綾誨瓙瀵硅薄鐨勫亸縐婚噺鐨勮礋鍊鹼紝瀹為檯涓婂氨鏄釜浠ヨˉ鐮佽〃紺虹殑int綾誨瀷鐨勫鹼紝鍦ㄨ綆楄櫄
           鍩虹被瀛愬璞¢鍦板潃鏃訛紝闇瑕佸皢璇ュ亸縐婚噺鍙栫粷瀵瑰肩浉鍔狅紝榪欎釜涓昏鏄負浜嗗拰铏氳〃
           涓彧鑳藉瓨鏀捐櫄鍑芥暟鍦板潃榪欎竴瑕佹眰鐩稿尯鍒紝鍥犱負鍦板潃鏄師鐮佽〃紺虹殑鏃犵鍙穒nt綾誨瀷
           鐨勫鹼級
       3.3. 鍏變韓
           鍏變韓琛ㄦ槑浜嗗湪瀵硅薄鐨勫唴瀛樼┖闂翠腑浠呬粎鑳藉鍖呭惈涓浠借櫄鍩虹被鐨勫瓙瀵硅薄錛屽茍涓旈氳繃
           鏌愮闂存帴鐨勬満鍒舵潵瀹屾垚鍏變韓鐨勫紩鐢ㄥ叧緋匯傚湪浠嬬粛瀹屾暣涓唴瀹瑰悗浼氶檮涓婃祴璇曚唬鐮侊紝
           浣撶幇榪欎簺鍐呭銆?br>    4. 鎬ц兘
       鐢變簬鏈変簡闂存帴鎬у拰鍏變韓鎬т袱涓壒寰侊紝鎵浠ュ喅瀹氫簡铏氱戶鎵夸綋緋諱笅鐨勫璞″湪璁塊棶鏃跺繀鐒?br>       浼氬湪鏃墮棿鍜岀┖闂翠笂涓庝竴鑸儏鍐墊湁杈冨ぇ涓嶅悓銆?br>       4.1. 鏃墮棿
           鍦ㄩ氳繃緇ф壙綾誨璞¤闂櫄鍩虹被瀵硅薄涓殑鎴愬憳錛堝寘鎷暟鎹垚鍛樺拰鍑芥暟鎴愬憳錛夋椂錛岄兘
           蹇呴』閫氳繃鏌愮闂存帴寮曠敤鏉ュ畬鎴愶紝榪欐牱浼氬鍔犲紩鐢ㄥ鍧鏃墮棿錛堝氨鍜岃櫄鍑芥暟涓鏍鳳級錛?br>           鍏跺疄灝辨槸璋冩暣this鎸囬拡浠ユ寚鍚戣櫄鍩虹被瀵硅薄錛屽彧涓嶈繃榪欎釜璋冩暣鏄繍琛屾椂闂存帴瀹屾垚鐨勩?br>           錛堝湪VC8涓氳繃鎵撳紑姹囩紪杈撳嚭錛屽彲浠ユ煡鐪?.cod鏂囦歡涓殑鍐呭錛屽湪璁塊棶铏氬熀綾誨璞?br>           鎴愬憳鏃朵細褰㈡垚涓夋潯mov闂存帴瀵誨潃璇彞錛岃屽湪璁塊棶涓鑸戶鎵跨被瀵硅薄鏃朵粎浠呭彧鏈変竴鏉ov
           甯擱噺鐩存帴瀵誨潃璇彞錛?br>       4.2. 絀洪棿
           鐢變簬鍏變韓鎵浠ヤ笉鍚屽湪瀵硅薄鍐呭瓨涓繚瀛樺浠借櫄鍩虹被瀛愬璞$殑鎷瘋礉錛岃繖鏍瘋緝涔嬪緇ф壙
           鑺傜渷絀洪棿銆?br>    5. 搴旂敤
       璋堜簡閭d箞澶氳璦鐗規у拰鍐呭錛岄偅涔堝湪浠涔堟儏鍐典笅闇瑕佷嬌鐢ㄨ櫄緇ф壙錛岃屼竴鑸簲璇ュ浣曚嬌
       鐢ㄥ憿錛?br>       榪欎釜闂鍏跺疄寰堥毦鏈夌瓟妗堬紝涓鑸儏鍐典笅濡傛灉浣犵‘鎬у嚭鐜板緇ф壙娌℃湁蹇呰錛屽繀欏昏鍏變韓
       鍩虹被瀛愬璞$殑鏃跺欏彲浠ヨ冭檻閲囩敤铏氱戶鎵垮叧緋伙紙C++鏍囧噯ios浣撶郴灝辨槸榪欐牱鐨勶級銆傜敱浜庢瘡
       涓涓戶鎵跨被閮藉繀欏誨寘鍚垵濮嬪寲璇彞鑰屽張浠呬粎鍙湪鏈搴曞眰瀛愮被涓皟鐢紝榪欐牱鍙兘灝變細浣?br>       寰楁煇浜涗笂灞傚瓙綾誨緱鍒扮殑铏氬熀綾誨瓙瀵硅薄鐨勭姸鎬佷笉鏄嚜宸辨墍鏈熸湜鐨勶紙鍥犱負鑷繁鐨勫垵濮嬪寲璇?br>       鍙ヨ鍘嬪埗浜嗭級錛屾墍浠ヤ竴鑸緩璁笉瑕佸湪铏氬熀綾諱腑鍖呭惈浠諱綍鏁版嵁鎴愬憳錛堜笉瑕佹湁鐘舵侊級錛屽彧
       鍙互浣滀負鎺ュ彛綾繪潵鎻愪緵銆?br>
闄勫綍錛氭祴璇曚唬鐮?br>#include <ctime>
#include <iostream>

/*
 * 甯︽湁鏁版嵁鎴愬憳鐨勫熀綾?br> */
struct CBaseClass1
{
    CBaseClass1( size_t i ) : m_val( i ) {}

    size_t m_val;
};
/*
 * 铏氭嫙緇ф壙浣撶郴
 */
struct CSubClassV1 : public virtual CBaseClass1
{
    CSubClassV1( size_t i ) : CBaseClass1( i ) {}
};

struct CSubClassV2 : public virtual CBaseClass1
{
    CSubClassV2( size_t i ) : CBaseClass1( i ) {}
};

struct CDiamondClass1 : public CSubClassV1, public CSubClassV2
{
    CDiamondClass1( size_t i ) : CBaseClass1( i ), CSubClassV1( i ), CSubClassV2( i ) {}
};

struct CDiamondSubClass1 : public CDiamondClass1
{
    CDiamondSubClass1( size_t i ) : CBaseClass1( i ), CDiamondClass1( i ) {}
};
/*
 * 姝e父緇ф壙浣撶郴
 */
struct CSubClassN1 : public CBaseClass1
{
    CSubClassN1( size_t i ) : CBaseClass1( i ) {}
};
struct CSubClassN2 : public CBaseClass1
{
    CSubClassN2( size_t i ) : CBaseClass1( i ) {}
};
struct CMultiClass1 : public CSubClassN1, public CSubClassN2
{
    CMultiClass1( size_t i ) : CSubClassN1( i ), CSubClassN2( i ) {}
};
struct CMultiSubClass1 : public CMultiClass1
{
    CMultiSubClass1( size_t i ) : CMultiClass1( i ) {}
};
/*
 * 涓嶅甫鏈夋暟鎹垚鍛樼殑鎺ュ彛鍩虹被
 */
struct CBaseClass2
{
    virtual void func() {};
    virtual ~CBaseClass2() {}
};
/*
 * 铏氭嫙緇ф壙浣撶郴
 */
// struct CBaseClassX { CBaseClassX() {i1 = i2 = 0xFFFFFFFF;} size_t i1, i2;};
struct CSubClassV3 : public virtual CBaseClass2
{
};
struct CSubClassV4 : public virtual CBaseClass2
{
};
struct CDiamondClass2 : public CSubClassV3, public CSubClassV4
{
};
struct CDiamondSubClass2 : public CDiamondClass2
{
};

/*
 * 姝e父緇ф壙浣撶郴
 */
struct CSubClassN3 : public CBaseClass2
{
};
struct CSubClassN4 : public CBaseClass2
{
};
struct CMultiClass2 : public CSubClassN3, public CSubClassN4
{
};
struct CMultiSubClass2 : public CMultiClass2
{
};

/*
 * 鍐呭瓨甯冨眬鐢ㄧ被澹版槑.
 */
struct CLayoutBase1
{
    CLayoutBase1() : m_val1( 0 ), m_val2( 1 ) {}

    size_t m_val1, m_val2;
};
struct CLayoutBase2
{
    CLayoutBase2() : m_val1( 3 ) {}

    size_t m_val1;
};
struct CLayoutSubClass1 : public virtual CBaseClass1, public CLayoutBase1, public CLayoutBase2
{
    CLayoutSubClass1() : CBaseClass1( 2 ) {}
};


#define MAX_TEST_COUNT 1000 * 1000 * 16
#define TIME_ELAPSE() ( std::clock() - start * 1.0 ) / CLOCKS_PER_SEC

int main( int argc, char *argv[] )
{
    /*
     * 綾諱綋緋諱腑鐨勫昂瀵?
     */
    std::cout << "================================ sizeof ================================" << std::endl;
    std::cout << "    ----------------------------------------------------------------" << std::endl;
    std::cout << "sizeof( CBaseClass1 )       = " << sizeof( CBaseClass1 ) << std::endl;
    std::cout << std::endl;
    std::cout << "sizeof( CSubClassV1 )       = " << sizeof( CSubClassV1 ) << std::endl;
    std::cout << "sizeof( CSubClassV2 )       = " << sizeof( CSubClassV2 ) << std::endl;
    std::cout << "sizeof( CDiamondClass1 )    = " << sizeof( CDiamondClass1 ) << std::endl;
    std::cout << "sizeof( CDiamondSubClass1 ) = " << sizeof( CDiamondSubClass1 ) << std::endl;
    std::cout << std::endl;
    std::cout << "sizeof( CSubClassN1 )       = " << sizeof( CSubClassN1 ) << std::endl;
    std::cout << "sizeof( CSubClassN2 )       = " << sizeof( CSubClassN2 ) << std::endl;
    std::cout << "sizeof( CMultiClass1 )      = " << sizeof( CMultiClass1 ) << std::endl;
    std::cout << "sizeof( CMultiSubClass1 )   = " << sizeof( CMultiSubClass1 ) << std::endl;

    std::cout << "    ----------------------------------------------------------------" << std::endl;
    std::cout << "sizeof( CBaseClass2 )       = " << sizeof( CBaseClass2 ) << std::endl;
    std::cout << std::endl;
    std::cout << "sizeof( CSubClassV3 )       = " << sizeof( CSubClassV3 ) << std::endl;
    std::cout << "sizeof( CSubClassV4 )       = " << sizeof( CSubClassV4 ) << std::endl;
    std::cout << "sizeof( CDiamondClass2 )    = " << sizeof( CDiamondClass2 ) << std::endl;
    std::cout << "sizeof( CDiamondSubClass2 ) = " << sizeof( CDiamondSubClass2 ) << std::endl;
    std::cout << std::endl;
    std::cout << "sizeof( CSubClassN3 )       = " << sizeof( CSubClassN3 ) << std::endl;
    std::cout << "sizeof( CSubClassN4 )       = " << sizeof( CSubClassN4 ) << std::endl;
    std::cout << "sizeof( CMultiClass2 )      = " << sizeof( CMultiClass2 ) << std::endl;
    std::cout << "sizeof( CMultiSubClass2 )   = " << sizeof( CMultiSubClass2 ) << std::endl;
    /*
     * 瀵硅薄鍐呭瓨甯冨眬
     */
    std::cout << "================================ layout ================================" << std::endl;
    std::cout << "    --------------------------------MI------------------------------" << std::endl;
    CLayoutSubClass1 *lsc = new CLayoutSubClass1;
    std::cout << "sizeof( CLayoutSubClass1 )   = " << sizeof( CLayoutSubClass1 ) << std::endl;
    std::cout << "CLayoutBase1 offset of CLayoutSubClass1 is " << (char*)(CLayoutBase1 *)lsc - (char*)lsc << std::endl;
    std::cout << "CBaseClass1  offset of CLayoutSubClass1 is " << (char*)(CBaseClass1  *)lsc - (char*)lsc << std::endl;
    std::cout << "CLayoutBase2 offset of CLayoutSubClass1 is " << (char*)(CLayoutBase2 *)lsc - (char*)lsc << std::endl;

    int *ptr = (int*)lsc;
    std::cout << "vbc in CLayoutSubClass1 is " << *(int*)ptr[3] << std::endl;

    delete lsc;

    std::cout << "    --------------------------------SI------------------------------" << std::endl;
    CSubClassV1 *scv1 = new CSubClassV1( 1 );
    std::cout << "sizeof( CSubClassV1 )   = " << sizeof( CSubClassV1 ) << std::endl;
    std::cout << "CBaseClass1 offset of CSubClassV1 is " << (char*)(CBaseClass1 *)scv1 - (char*)scv1 << std::endl;

    ptr = (int*)scv1;
    std::cout << "vbc in CSubClassV1 is " << *(int*)ptr[0] << std::endl;

    delete scv1;

    /*
     * 鎬ц兘嫻嬭瘯
     */
    std::cout << "================================ Performance ================================" << std::endl;
    double times[4];
    size_t idx = 0;

    CSubClassV1 *ptr1 = new CDiamondClass1( 1 );
    std::clock_t start = std::clock();
    {
        for ( size_t i = 0; i < MAX_TEST_COUNT; ++i )
            ptr1->m_val = i;
    }
    times[idx++] = TIME_ELAPSE();
    delete static_cast<CDiamondClass1*>( ptr1 );

    CSubClassN1 *ptr2 = new CMultiClass1( 0 );
    start = std::clock();
    {
        for ( size_t i = 0; i < MAX_TEST_COUNT; ++i )
            ptr2->m_val = i;
    }
    times[idx++] = TIME_ELAPSE();
    delete static_cast<CMultiClass1*>( ptr2 );

    std::cout << "CSubClassV1::ptr1->m_val " << times[0] << " s" << std::endl;
    std::cout << "CSubClassN1::ptr2->m_val " << times[1] << " s" << std::endl;

    return 0;
}

嫻嬭瘯鐜錛?br>    杞歡鐜錛歏isual Studio2005 Pro + SP1, boost1.34.0
    紜歡鐜錛歅entiumD 3.0GHz, 4G RAM
嫻嬭瘯鏁版嵁錛?br>================================ sizeof ================================
    ----------------------------------------------------------------
sizeof( CBaseClass1 )       = 4

sizeof( CSubClassV1 )       = 8
sizeof( CSubClassV2 )       = 8
sizeof( CDiamondClass1 )    = 12
sizeof( CDiamondSubClass1 ) = 12

sizeof( CSubClassN1 )       = 4
sizeof( CSubClassN2 )       = 4
sizeof( CMultiClass1 )      = 8
sizeof( CMultiSubClass1 )   = 8
    ----------------------------------------------------------------
sizeof( CBaseClass2 )       = 4

sizeof( CSubClassV3 )       = 8
sizeof( CSubClassV4 )       = 8
sizeof( CDiamondClass2 )    = 12
sizeof( CDiamondSubClass2 ) = 12

sizeof( CSubClassN3 )       = 4
sizeof( CSubClassN4 )       = 4
sizeof( CMultiClass2 )      = 8
sizeof( CMultiSubClass2 )   = 8
================================ layout ================================
    --------------------------------MI------------------------------
sizeof( CLayoutSubClass1 )   = 20
CLayoutBase1 offset of CLayoutSubClass1 is 0
CBaseClass1  offset of CLayoutSubClass1 is 16
CLayoutBase2 offset of CLayoutSubClass1 is 8
vbc in CLayoutSubClass1 is -12
    --------------------------------SI------------------------------
sizeof( CSubClassV1 )   = 8
CBaseClass1 offset of CSubClassV1 is 4
vbc in CSubClassV1 is 0
================================ Performance ================================
CSubClassV1::ptr1->m_val 0.062 s
CSubClassN1::ptr2->m_val 0.016 s

緇撴灉鍒嗘瀽錛?br>    1. 鐢變簬铏氱戶鎵垮紩鍏ョ殑闂存帴鎬ф寚閽堟墍浠ュ鑷翠簡铏氱戶鎵跨被鐨勫昂瀵鎬細澧炲姞4涓瓧鑺傦紱
    2. 鐢盠ayout杈撳嚭鍙互鐪嬪嚭錛岃櫄鍩虹被瀛愬璞¤鏀懼湪浜嗗璞$殑灝鵑儴錛堝亸縐諱負16錛夛紝騫朵笖vbc
       鎸囬拡蹇呴』绱х揣鐨勬帴鍦ㄨ櫄鍩虹被瀛愬璞$殑鍓嶉潰錛屾墍浠bc鎸囬拡鎵鎸囧悜鐨勫唴瀹逛負“鍋忕Щ - 4”錛?br>    3. 鐢變簬VC8灝嗗亸縐繪斁鍦ㄤ簡铏氬嚱鏁拌〃涓紝鎵浠ヤ負浜嗗尯鍒嗗嚱鏁板湴鍧鍜屽亸縐伙紝鎵浠ュ亸縐繪槸鐢ㄨˉ
       鐮乮nt琛ㄧず鐨勮礋鍊鹼紱
    4. 闂存帴鎬у彲浠ラ氳繃鎬ц兘鏉ョ湅鍑猴紝鍦ㄨ櫄緇ф壙浣撶郴鍚岄氳繃鎸囬拡璁塊棶鎴愬憳鏃剁殑鏃墮棿涓鑸槸涓鑸?br>       綾昏闂儏鍐典笅鐨?鍊嶅乏鍙籌紝絎﹀悎姹囩紪璇█杈撳嚭鏂囦歡涓殑姹囩紪璇彞鐨勫畨鎺掋?

Sandy 2008-10-16 22:19 鍙戣〃璇勮
]]>
铏氭嫙緇ф壙鍏ラ棬http://www.shnenglu.com/SpringSnow/articles/64206.htmlSandySandyThu, 16 Oct 2008 13:48:00 GMThttp://www.shnenglu.com/SpringSnow/articles/64206.htmlhttp://www.shnenglu.com/SpringSnow/comments/64206.htmlhttp://www.shnenglu.com/SpringSnow/articles/64206.html#Feedback1http://www.shnenglu.com/SpringSnow/comments/commentRss/64206.htmlhttp://www.shnenglu.com/SpringSnow/services/trackbacks/64206.html閾炬帴錛?a href="http://www.shnenglu.com/franksunny/archive/2008/10/16/64168.html">
http://www.shnenglu.com/franksunny/archive/2008/10/16/64168.html

鍘熸枃錛?br>

涓轟粈涔堣寮曞叆铏氭嫙緇ф壙錛?/span>

铏氭嫙緇ф壙鍦ㄤ竴鑸殑搴旂敤涓緢灝戠敤鍒幫紝鎵浠ヤ篃寰寰琚拷瑙嗭紝榪欎篃涓昏鏄洜涓哄湪C++涓紝澶氶噸緇ф壙鏄笉鎺ㄨ崘鐨勶紝涔熷茍涓嶅父鐢紝鑰屼竴鏃︾寮浜嗗閲嶇戶鎵匡紝铏氭嫙緇ф壙灝卞畬鍏ㄥけ鍘諱簡瀛樺湪鐨勫繀瑕侊紙鍥犱負榪欐牱鍙細闄嶄綆鏁堢巼鍜屽崰鐢ㄦ洿澶氱殑絀洪棿錛屽叧浜庤繖涓鐐癸紝鎴戣嚜宸辮繕娌℃湁澶娣卞埢鐨勭悊瑙o紝鏈夊叴瓚g殑鍙互鐪嬬綉緇滀笂鐧芥潹鐨勪綔鍝?/span>銆?/span>RTTI銆佽櫄鍑芥暟鍜岃櫄鍩?span>綾葷殑寮閿鍒嗘瀽鍙婁嬌鐢ㄦ寚瀵?span>銆?/span>錛岃瀹炶瘽鎴戠洰鍓嶈繕娌$湅寰楀緢鏄庣櫧錛岄珮浜哄彲浠ユ寚鐐逛笅鎴戯級銆?/span>

浠ヤ笅闈㈢殑涓涓緥瀛愪負渚嬶細

#include <iostream.h>

#include <memory.h>

class CA

{

    int k; //濡傛灉鍩虹被娌℃湁鏁版嵁鎴愬憳錛屽垯鍦ㄨ繖閲屽閲嶇戶鎵跨紪璇戜笉浼氬嚭鐜頒簩涔夋?/span>

public:

    void f() {cout << "CA::f" << endl;}

};

 

class CB : public CA

{

};

 

class CC : public CA

{

};

 

class CD : public CB, public CC

{

};

 

void main()

{

    CD d;

    d.f();

}

褰撶紪璇戜笂榪頒唬鐮佹椂錛屾垜浠細鏀跺埌濡備笅鐨勯敊璇彁紺猴細

error C2385: 'CD::f' is ambiguous

鍗崇紪璇戝櫒鏃犳硶紜畾浣犲湪d.f()涓璋冪敤鐨勫嚱鏁?/span>f鍒板簳鏄摢涓涓傝繖閲屽彲鑳戒細璁╀漢瑙夊緱鏈変簺濂囨紝鍛藉悕鍙畾涔変簡涓涓?/span>CA::f錛屾棦鐒跺ぇ瀹墮兘媧劇敓鑷?/span>CA錛岄偅鑷劧灝辨槸璋冪敤鐨?/span>CA::f錛屼負浠涔堣繕鏃犳硶紜畾鍛紵

榪欐槸鍥犱負緙栬瘧鍣ㄥ湪榪涜緙栬瘧鐨勬椂鍊欙紝闇瑕佺‘瀹氬瓙綾葷殑鍑芥暟瀹氫箟錛屽CA::f鏄‘瀹氱殑錛岄偅涔堝湪緙栬瘧CB銆?/span>CC鏃惰繕闇瑕佸湪緙栬瘧鍣ㄧ殑璇硶鏍戜腑鐢熸垚CB::f錛?/span>CC::f絳夋爣璇嗭紝閭d箞錛屽湪緙栬瘧CD鐨勬椂鍊欙紝鐢變簬CB銆?/span>CC閮芥湁涓涓嚱鏁?/span>f錛屾鏃訛紝緙栬瘧鍣ㄥ皢璇曞浘鐢熸垚榪欎袱涓?/span>CD::f鏍囪瘑錛屾樉鐒惰繖鏃跺氨瑕佹姤閿欎簡銆傦紙褰撴垜浠笉浣跨敤CD::f鐨勬椂鍊欙紝浠ヤ笂鏍囪瘑閮戒笉浼氱敓鎴愶紝鎵浠ワ紝濡傛灉鍘繪帀d.f()涓鍙ワ紝紼嬪簭灝嗛『鍒╅氳繃緙栬瘧錛?/span>

 

瑕佽В鍐寵繖涓棶棰橈紝鏈変袱涓柟娉曪細

1銆侀噸杞藉嚱鏁?/span>f()錛氭鏃剁敱浜庢垜浠槑紜畾涔変簡CD::f錛岀紪璇戝櫒媯鏌ュ埌CD::f()璋冪敤鏃跺氨鏃犻渶鍐嶅儚涓婇潰涓鏍峰幓閫愮駭鐢熸垚CD::f鏍囪瘑浜嗭紱

姝ゆ椂CD鐨勫厓绱犵粨鏋勫涓嬶細

|CB(CA)|

|CC(CA)|

鏁呮鏃剁殑sizeof(CD) = 8;錛?/span>CB銆?/span>CC鍚勬湁涓涓厓绱?/span>k錛?/span>

2銆佷嬌鐢ㄨ櫄鎷熺戶鎵匡細铏氭嫙緇ф壙鍙堢О浣滃叡浜戶鎵匡紝榪欑鍏變韓鍏跺疄涔熸槸緙栬瘧鏈熼棿瀹炵幇鐨勶紝褰撲嬌鐢ㄨ櫄鎷熺戶鎵挎椂錛屼笂闈㈢殑紼嬪簭灝嗗彉鎴愪笅闈㈢殑褰㈠紡錛?/span>

#include <iostream.h>

#include <memory.h>

class CA

{

    int k;

public:

    void f() {cout << "CA::f" << endl;}

};

 

class CB : virtual public CA //涔熸湁涓縐嶅啓娉曟槸class CB : public virtual CA

{                       //瀹為檯涓婅繖涓ょ鏂規硶閮藉彲浠?/span>

};

 

class CC : virtual public CA

{

};

 

class CD : public CB, public CC

{

};

 

void main()

{

    CD d;

    d.f();

}

姝ゆ椂錛屽綋緙栬瘧鍣ㄧ‘瀹?/span>d.f()璋冪敤鐨勫叿浣撳惈涔夋椂錛屽皢鐢熸垚濡備笅鐨?/span>CD緇撴瀯錛?/span>

|CB|

|CC|

|CA|

鍚屾椂錛屽湪CB銆?/span>CC涓兘鍒嗗埆鍖呭惈浜嗕竴涓寚鍚?/span>CA鐨勮櫄鍩虹被鎸囬拡鍒楄〃vbptr錛?/span>virtual base table pointer錛夛紝鍏朵腑璁板綍鐨勬槸浠?/span>CB銆?/span>CC鐨勫厓绱犲埌CA鐨勫厓绱犱箣闂寸殑鍋忕Щ閲忋傛鏃訛紝涓嶄細鐢熸垚鍚勫瓙綾葷殑鍑芥暟f鏍囪瘑錛岄櫎闈炲瓙綾婚噸杞戒簡璇ュ嚱鏁幫紝浠庤岃揪鍒?#8220;鍏變韓”鐨勭洰鐨勶紙榪欓噷鐨勫叿浣撳唴瀛樺竷灞錛屽彲浠ュ弬鐪嬮捇鐭沖瀷緇ф壙鍐呭瓨甯冨眬錛屽湪鐧芥潹鐨勯偅綃囨枃绔犱腑涔熸湁錛夈?/span>

涔熸鍥犳錛屾鏃剁殑sizeof(CD) = 12錛堜袱涓?/span>vbptr + sizoef(int)錛?/span>;

 

鍙︽敞錛?/span>

濡傛灉CB錛?/span>CC涓悇瀹氫箟涓涓?/span>int鍨嬪彉閲忥紝鍒?/span>sizeof(CD)灝卞彉鎴?/span>20(涓や釜vbptr + 3涓?/span>sizoef(int)

濡傛灉CA涓坊鍔犱竴涓?/span>virtual void f1(){}錛?/span>sizeof(CD) = 16錛堜袱涓?/span>vbptr + sizoef(int)+vptr錛?/span>;

鍐嶆坊鍔?/span>virtual void f2(){}錛?/span>sizeof(CD) = 16涓嶅彉銆傚師鍥犲涓嬫墍紺猴細甯︽湁铏氬嚱鏁扮殑綾伙紝鍏跺唴瀛樺竷灞涓婂寘鍚竴涓寚鍚戣櫄鍑芥暟鍒楄〃鐨勬寚閽堬紙vptr錛夛紝榪欒窡鏈夊嚑涓櫄鍑芥暟鏃犲叧銆?/span>

浠ヤ笂鍐呭娑夊強鍒扮被瀵硅薄鍐呭瓨甯冨眬闂錛屾湰浜鴻繕闅句互鍋氳繃澶氬睍寮錛屽厛璐磋繖涔堝錛屾湰綃囨枃绔犲彧鏄冭檻瀵逛簬铏氭嫙緇ф壙榪涜鍏ラ棬錛岃嚦浜庢晥鐜囥佸簲鐢ㄧ瓑鏈綔灞曞紑銆傛湰鏂囧湪緗戜笂鏂囩珷鍩虹涓婁慨鏀逛簡涓嬭屽緱姝ょ瘒錛屽師鏂囪澆浜?/span>http://blog.csdn.net/billdavid/archive/2004/06/23/24317.aspx

鍙﹀鍏充簬铏氱戶鎵垮拰铏氬熀綾葷殑璁ㄨ錛屽崥瀹㈠洯鏈夌瘒鏂囩珷銆?/span>铏氱戶鎵夸笌铏氬熀綾葷殑鏈川銆嬶紝鎬葷粨寰楁洿涓鴻緇嗕竴鐐廣?/span>



Sandy 2008-10-16 21:48 鍙戣〃璇勮
]]>
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
              精品不卡在线| 国产精品久久久久久影院8一贰佰| 国产亚洲欧美一级| 久久蜜臀精品av| 久久亚洲精品一区二区| 最近看过的日韩成人| 亚洲日本理论电影| 欧美日韩免费在线| 久久www成人_看片免费不卡| 欧美在线精品一区| 91久久精品网| 亚洲午夜在线视频| 黄色一区二区在线| 最新成人av网站| 国产精品自在欧美一区| 美女性感视频久久久| 欧美日韩1区2区| 欧美视频精品在线观看| 亚洲一区精品在线| 伊人久久噜噜噜躁狠狠躁| 亚洲第一中文字幕| 国产精品日韩电影| 欧美国产视频在线| 国产精品欧美经典| 欧美黄色精品| 国产精品视频yy9299一区| 久久综合一区| 欧美性大战久久久久久久| 老司机精品视频一区二区三区| 欧美精品在线观看| 久久亚洲综合网| 国产精品久久久久三级| 欧美激情无毛| 狠狠色综合色综合网络| 野花国产精品入口| 亚洲美女毛片| 久久午夜羞羞影院免费观看| 亚洲嫩草精品久久| 欧美极品一区| 欧美国产一区二区| 国产一区二区精品丝袜| 亚洲性线免费观看视频成熟| 亚洲精品精选| 老牛影视一区二区三区| 久久久亚洲高清| 国产精品一区二区在线观看不卡| 亚洲欧洲午夜| 亚洲欧洲精品一区二区三区不卡 | 蜜臀va亚洲va欧美va天堂| 国产精品久久久久久久久久免费看| 欧美激情一区二区三区蜜桃视频| 黄色精品一区二区| 亚洲欧美影院| 欧美一区二区三区在线播放| 欧美性色aⅴ视频一区日韩精品| 亚洲国产精品一区二区第四页av | 日韩视频免费在线| 欧美 亚欧 日韩视频在线| 麻豆成人在线播放| 狠狠色噜噜狠狠色综合久| 久久国产精品一区二区三区| 久久精品国产精品亚洲精品| 国产深夜精品福利| 欧美一区二区三区电影在线观看| 欧美一区影院| 国产精品一区二区三区久久| 亚洲欧美日韩精品久久奇米色影视| 亚洲欧美日韩精品久久久久| 国产精品99免费看| 亚洲淫片在线视频| 久久国产精品久久w女人spa| 国产亚洲一区在线播放| 久久久国产亚洲精品| 欧美国产激情二区三区| 日韩亚洲欧美成人一区| 欧美日韩一区二区精品| 亚洲午夜国产一区99re久久| 久久电影一区| 136国产福利精品导航| 欧美极品一区| 国产精品a久久久久| 在线亚洲美日韩| 国产精品久久久久久久久免费樱桃 | 久久精品观看| 亚洲高清一区二| 欧美日本视频在线| 亚洲欧美日韩中文播放| 免费在线看一区| 亚洲一区二区三区在线视频| 国产毛片一区| 免费观看成人| 亚洲自拍啪啪| 亚洲国产天堂久久综合网| 亚洲视屏一区| 精品91视频| 欧美日韩午夜精品| 久久精品99| 一本综合久久| 能在线观看的日韩av| 亚洲视频综合在线| 在线成人免费视频| 国产精品红桃| 欧美高清视频| 欧美在线视频一区| 99精品免费| 欧美电影电视剧在线观看| 亚洲欧美一区二区三区在线| 亚洲国产精品久久久久| 国产精品亚洲视频| 欧美日韩国产美女| 久久―日本道色综合久久| 在线亚洲欧美视频| 亚洲国产黄色片| 久久综合婷婷| 欧美一区二区三区在线播放| 一区二区三区四区精品| 亚洲春色另类小说| 国语对白精品一区二区| 国产精品免费小视频| 欧美日韩不卡在线| 欧美 日韩 国产 一区| 久久爱www久久做| 亚洲欧美综合网| 亚洲一品av免费观看| 亚洲久久一区二区| 亚洲黄色在线| 亚洲国产精品综合| 欧美国产高清| 欧美成人久久| 美乳少妇欧美精品| 久久综合精品一区| 久久一区激情| 久久中文字幕导航| 老色鬼精品视频在线观看播放| 久久精品成人一区二区三区 | 国产精品99久久不卡二区| 亚洲精品国产精品乱码不99| 亚洲国产va精品久久久不卡综合| 国产原创一区二区| 国内外成人免费激情在线视频网站| 国产精品日韩在线一区| 国产精品尤物| 国产亚洲一区二区三区| 国产视频亚洲精品| 国产一区二区在线免费观看| 国产一区二区三区四区三区四| 国产日韩精品视频一区| 国内久久视频| 亚洲国产精品va在线看黑人| 亚洲精品视频啊美女在线直播| 亚洲精品裸体| 亚洲精选成人| 欧美成人综合一区| 亚洲国产精品123| 亚洲每日在线| 亚洲免费视频中文字幕| 欧美一区二区免费视频| 久久亚洲精品欧美| 欧美精品色一区二区三区| 欧美日韩国产不卡在线看| 欧美午夜精品一区二区三区| 国产欧美一区在线| 亚洲国产精品ⅴa在线观看 | 国产欧美在线看| 精品动漫3d一区二区三区免费版 | 欧美在线视频免费播放| 久久久久国产精品www| 欧美大胆成人| 亚洲一区二区三区精品在线| 久久成人精品| 欧美日韩国产va另类| 国产欧美欧美| 亚洲人成小说网站色在线| 亚洲一区高清| 免费一区视频| 亚洲香蕉伊综合在人在线视看| 久久精品国产成人| 欧美日韩国产综合网 | 在线免费观看日本欧美| 亚洲视频一区| 欧美 日韩 国产精品免费观看| 亚洲免费观看| 久久这里只有精品视频首页| 欧美日韩在线播放三区四区| 国语自产精品视频在线看一大j8 | 蜜桃精品久久久久久久免费影院| 亚洲免费成人av| 久久天堂国产精品| 国产精品中文在线| 亚洲视频在线观看| 欧美不卡在线| 欧美在线首页| 国产精品美女一区二区| 亚洲精品国精品久久99热一 | 亚洲精品日韩激情在线电影| 久久九九久精品国产免费直播| 一本色道久久88精品综合| 免费视频一区| 亚洲国产福利在线| 久久夜色精品国产亚洲aⅴ|