锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 璧栧媷嫻╋紙http://laiyonghao.com錛?br /> 澹版槑錛氭湰鏂囨簮鑷?Danny Kalev 鍦?2011 騫?6 鏈?21 鏃ュ彂琛ㄧ殑銆奣he Biggest Changes in C++11(and Why You Should Care)銆嬩竴鏂囷紝鍑犱箮鎵鏈夊唴瀹歸兘鎼簡榪囨潵錛屼絾涓嶆槸鍏ㄦ枃鐓ц瘧錛屾湁鍥版儜涔嬪錛岃鍙傝鍘熸枃錛?a >http://www.softwarequalityconnection.com/2011/06/the-biggest-changes-in-c11-and-why-you-should-care/ 錛夈?br /> 娉細浣滆?Danny Kalev 鏇炬槸 C++ 鏍囧噯濮斿憳浼氭垚鍛樸?/p> Lambda 琛ㄨ揪寮忕殑褰㈠紡鏄繖鏍風殑錛?br /> 鍦?C++03 涓紝澹版槑瀵硅薄鐨勫悓鏃跺繀欏繪寚鏄庡叾綾誨瀷錛屽叾瀹炲ぇ澶氭暟鎯呭喌涓嬶紝澹版槑瀵硅薄鐨勫悓鏃朵篃浼氬寘鎷竴涓垵濮嬪鹼紝C++11 鍦ㄨ繖縐嶆儏鍐典笅灝辮兘澶熻浣犲0鏄庡璞℃椂涓嶅啀鎸囧畾綾誨瀷浜嗭細 C++ 鏈灝戞湁 4 縐嶄笉鍚岀殑鍒濆鍖栧艦寮忥紝濡傛嫭鍙峰唴鍒濆鍖栵紝瑙侊細 鍍忎互涓嬪艦寮忕殑鍑芥暟錛?br /> nullptr 鏄竴涓柊鐨?C++ 鍏抽敭瀛楋紝瀹冩槸絀烘寚閽堝父閲忥紝瀹冩槸鐢ㄦ潵鏇夸唬楂橀闄╃殑 NULL 瀹忓拰 0 瀛楅潰閲忕殑銆俷ullptr 鏄己綾誨瀷鐨勶細 C++11 涓瀯閫犲嚱鏁板彲浠ヨ皟鐢ㄥ悓涓涓被鐨勫彟涓涓瀯閫犲嚱鏁幫細 鍦?C++03 涓殑寮曠敤綾誨瀷鏄彧緇戝畾宸﹀肩殑錛孋++11 寮曠敤涓涓柊鐨勫紩鐢ㄧ被鍨嬪彨鍙沖煎紩鐢ㄧ被鍨嬶紝瀹冩槸緇戝畾鍒板彸鍊肩殑錛屽涓存椂瀵硅薄鎴栧瓧闈㈤噺銆?br /> 澧炲姞鍙沖煎紩鐢ㄧ殑涓昏鍘熷洜鏄負浜嗗疄鐜?move 璇箟銆備笌浼犵粺鐨勬嫹璐濅笉鍚岋紝move 鐨勬剰鎬濇槸鐩爣瀵硅薄“紿冨彇”鍘熷璞$殑璧勬簮錛屽茍灝嗘簮緗簬“絀?#8221;鐘舵併傚綋鎷瘋礉涓涓璞℃椂錛屽叾瀹炰唬浠鋒槀璐典笖鏃犲繀瑕侊紝move 鎿嶄綔灝卞彲浠ユ浛浠e畠銆傚鍦? string 浜ゆ崲鐨勬椂鍊欙紝浣跨敤 move 鎰忎箟灝辨湁宸ㄥぇ鐨勬ц兘鎻愬崌錛屽鍘熸柟妗堟槸榪欐牱鐨勶細 闄?TR1 鍖呭惈鐨勬柊瀹瑰櫒錛坲nordered_set, unordered_map, unordered_multiset, 鍜寀nordered_multimap錛夛紝榪樻湁涓浜涙柊鐨勫簱錛屽姝e垯琛ㄨ揪寮忥紝tuple錛屽嚱鏁板璞″皝瑁呭櫒絳夈備笅闈粙緇嶄竴浜?C++11 鐨勬爣鍑嗗簱鏂扮壒鎬э細 浠庣▼搴忓憳鐨勮搴︽潵鐪嬶紝C++11 鏈閲嶈鐨勭壒鎬у氨鏄茍鍙戜簡銆侰++11 鎻愪緵浜?thread 綾伙紝涔熸彁渚涗簡 promise 鍜?future 鐢ㄤ互騫跺彂鐜涓殑鍚屾錛岀敤 async() 鍑芥暟妯℃澘鎵ц騫跺彂浠誨姟錛屽拰 thread_local 瀛樺偍澹版槑涓虹壒瀹氱嚎紼嬬嫭鍗犵殑鏁版嵁錛岃繖閲岋紙http://www.devx.com/SpecialReports/Article/38883錛夋湁涓涓畝鍗?鐨?C++11 綰跨▼搴撴暀紼嬶紙鑻辨枃錛夈?/p> C++98 瀹氫箟鐨勫敮涓鐨勬櫤鑳芥寚閽堢被 auto_ptr 宸茬粡琚純鐢紝C++11 寮曞叆浜嗘柊鐨勬櫤鑳介拡瀵圭被 shared_ptr 鍜?unique_ptr銆傚畠浠兘鏄爣鍑嗗簱鐨勫叾瀹冪粍浠跺吋瀹癸紝鍙互瀹夊叏鍦版妸鏅鴻兘鎸囬拡瀛樺叆鏍囧噯瀹瑰櫒錛屼篃鍙互瀹夊叏鍦扮敤鏍囧噯綆楁硶“鍊掕吘”瀹冧滑銆?/p> 涓昏鏄?all_of()銆乤ny_of() 鍜?none_of()錛屼笅闈㈡槸渚嬪瓙錛?br /> Function/bind鍙互鏄竴涓緢綆鍗曠殑璇濋錛屽洜涓哄畠鍏跺疄涓嶈繃灝辨槸涓涓硾鍨嬬殑鍑芥暟鎸囬拡銆備絾鏄鏋滈偅涔堟潵璋堬紝灝辨病鎰忔濅簡錛屼篃鐘笉涓婂啓榪欑瘒涓滆タ銆傚湪鎴戠湅鏉ワ紝榪欎釜浜嬫儏瑕佽鐨勮瘽錛屽氨搴旇璁查忥紝璁插埌鍥炶皟錛坈allback錛夈佷唬鐞嗭紙delegate錛夈佷俊鍙鳳紙signal錛夊拰娑堟伅浼犻掞紙messaging錛夌殑灞傞潰錛屽洜涓哄畠紜疄鏄お閲嶈浜嗐傝繖涓瘽棰樹笉浣嗕笌闈㈠悜瀵硅薄鐨勬牳蹇冩濇兂瀵嗗垏鐩稿叧錛岃屼笖鏄潰鍚戝璞′袱澶ф祦媧句箣闂翠氦閿嬬殑涓績銆傚洿緇曡繖涓棶棰樼殑鎬濊冨拰浜夎錛屽嚑涔庢妸20騫存潵鎵鏈変富嫻佺殑緙栫▼騫沖彴鍜岀紪紼嬭璦閮芥悈榪涙潵浜嗐傛墍浠ワ紝濡傛灉璇﹀敖閾洪檲錛岃繖涓瘽棰樼洿鎺ュ彲浠ュ啓涓鏈功銆?/p>
鍐欎功鎴戝綋鐒舵病閭d釜姘村鉤錛屼絾榪欎釜棰樼洰紜疄涓鐩存兂鍔ㄤ竴鍔ㄣ傜劧鑰岃繖涓富棰樺疄鍦ㄥお澶э紝鎴戝疄鍦ㄦ病鏈夌簿鍔涙妸瀹冨畬鏁寸殑鍐欎笅鏉ワ紱榪欎釜涓婚涔熷緢娣憋紝鐗瑰埆鏄秹鍙婂埌騫跺彂鐜鏈夊叧鐨勮瘽棰橈紝鎴戠殑鐞嗚В榪橀潪甯歌偆嫻咃紝鎬昏寰楁垜璁よ瘑鐨勫緢澶氶珮鎵嬮兘姣旀垜鏇存湁璧勬牸鍐欒繖涓瘽棰樸傛墍浠ョ姽璞簡寰堜箙錛岃涓嶈鐜板湪鍐欙紝璇ユ庝箞鍐欍傛渶鍚庢垜瑙夊緱錛岀‘瀹炰笉鑳芥妸涓綃囧崥瀹㈡枃绔犲啓鎴愪竴鏈?0騫撮潰鍚戝璞℃妧鏈彶璁幫紝鎵浠ュ喅瀹氫繚鐣欏ぇ鐨勬灦鏋勶紝浣嗘槸瀵瑰叾涓叿浣撶殑鎶鏈粏鑺傜偣鍒頒負姝€傛垜涓嶄細鍘昏緇嗗湴鍒椾婦浠g爜錛屽垎鏋愬璞$殑鍐呭瓨甯冨眬錛岀敾紺烘剰鍥撅紝浣嗘槸浼氭妸鏈閲嶈鐨勭粨璁哄拰瑙傜偣鍐欎笅鏉ワ紝璇村緱濂藉惉涓鐐規(guī)槸鎻愮翰鎸堥錛岃鐨勪笉濂藉惉灝辨槸璇剦涓嶈銆備絾鏃犺濡備綍錛屾垜鎯寵繖鏍蜂竴綃囦笢瑗匡紝涓鏄皥璋堟垜瀵硅繖涓簨鎯呯殑鐪嬫硶錛屼簩鏄?#8220;鎶涚爾寮曠帀”錛屽紩鏉ラ珮鎵嬬殑鍏蟲敞錛屽紩鍑烘洿娣卞埢鍜屽畬鏁寸殑鍙欒堪銆?/p>
涓嬮潰寮濮嬨?/p>
0. 紼嬪簭璁捐鏈変竴涓寖寮忥紙paradigm錛夐棶棰樸傛墍璋撹寖寮忥紝灝辨槸緇勭粐紼嬪簭鐨勫熀鏈濇兂錛岃岃繖涓熀鏈濇兂錛屽弽鏄犱簡紼嬪簭璁捐鑰呭紼嬪簭鐨勪竴涓熀鏈殑鍝插瑙傦紝涔熷氨鏄錛屼粬璁や負紼嬪簭鐨勬湰璐ㄦ槸浠涔堬紝浠栬涓轟竴涓ぇ鐨勭▼搴忔槸鐢變粈涔堢粍鎴愮殑銆傝岃繖錛屽張璺熶粬瀵逛簬鐜板疄涓栫晫鐨勭湅娉曟湁鍏熾傛樉鐒訛紝榪欐牱鐨勭湅娉曚笉鍙兘鏈夊緢澶氱銆傜紪紼嬩綔涓轟竴闂ㄨ涓氾紝鐙珛瀛樺湪蹇?0騫翠簡錛屼絾鏄墍鍑虹幇鐨勮寖寮忎笉榪囦笁縐嶁斺旇繃紼嬭寖寮忋佸嚱鏁拌寖寮忋佸璞¤寖寮忋傚叾涓嚱鏁拌寖寮忎笌鐜板疄涓栫晫宸窛姣旇緝澶э紝鍦ㄨ繖閲屼笉璁ㄨ銆傝岃繃紼嬭寖寮忓拰瀵硅薄鑼冨紡鍙互瑙嗕負瀵圭▼搴忔湰璐ㄧ殑涓ょ鏍規(guī)湰涓嶅悓鐨勭湅娉曪紝鑰屼笖鑳藉鍒嗗埆鍦ㄧ幇瀹炰笘鐣屼腑鎵懼埌鐩稿簲鐨勬槧灝勩?br>榪囩▼鑼冨紡璁や負錛岀▼搴忔槸鐢變竴涓張涓涓繃紼嬬粡榪囬『搴忋侀夋嫨鍜屽驚鐜殑緇撴瀯緇勫悎鑰屾垚銆傚弽鏄犲湪鐜板疄涓栫晫錛岃繃紼嬭寖寮忎綋鐜頒簡鍔沖姩鍒嗗伐涔嬪墠“鍏ㄨ兘浜?#8221;鐨勫伐浣滅壒鐐光斺旀墍鏈夌殑浜嬫儏閮借兘騫詫紝鎵鏈夌殑璧勬簮閮芥槸鎴戠殑錛屽彧涓嶈繃寰楀叿浣撶殑浜嬫儏寰椾竴姝ユ鍦版潵鍋氥? 瀵硅薄鑼冨紡涓庤繃紼嬭寖寮忕浉姣旓紝鏈変笁涓獊鍑虹殑浼樺娍錛岀涓錛岀敱浜庡疄鐜頒簡閫昏緫涓婄殑鍒嗗伐錛岄檷浣庝簡澶ц妯$▼搴忕殑寮鍙戦毦搴︺傜浜岋紝鐏墊椿鎬ф洿濂解斺旇嫢騫插璞″湪涓璧鳳紝鍙互鐏墊椿緇勫悎錛屽彲浠ヤ互涓嶅悓鐨勬柟寮忓崗浣滐紝瀹屾垚涓嶅悓鐨勪換鍔★紝涔熷彲浠ョ伒媧葷殑鏇挎崲鍜屽崌綰с傜涓夛紝瀵硅薄鑼冨紡鏇村姞閫傚簲鍥懼艦鍖栥佺綉緇滃寲銆佹秷鎭┍鍔ㄧ殑鐜頒唬璁$畻鐜銆?/p>
鎵浠ワ紝杈冧箣浜庤繃紼嬭寖寮忥紝瀵硅薄鑼冨紡錛屾垨鑰呰“闈㈠悜瀵硅薄”錛岀‘瀹炴槸鏇村叿浼樺娍鐨勭紪紼嬭寖寮忋傛渶榪戠湅鍒頒竴浜涙枃绔犳姩鍑婚潰鍚戝璞★紝璇撮潰鍚戝璞℃槸鑳℃壇錛屾垜璁や負瑕佸叿浣撳垎鏋愩傚闈㈠悜瀵硅薄鐨勪竴閮ㄥ垎鎵硅瘎錛屾槸鍐茬潃涓繪祦鐨?#8220;闈㈠悜瀵硅薄”璇█鍘葷殑錛岃繖紜疄鏄湁閬撶悊鐨勶紝鎴戝湪涓嬮潰涔熶細璋堝埌錛岃屼笖浼氶獋寰楁洿鐙犮傝屽彟涓涓壒璇勭殑澹伴煶錛屼富瑕佽屾潵鑷猄TL涔嬬埗Alex Stepanov錛屼粬璇寸殑褰撶劧鏈変粬鐨勯亾鐞嗭紝涓嶈繃瑕佺煡閬撹鐗涗漢鏄墠鑻忚仈鑾柉縐戝浗绔嬬綏钂欒绱㈠か澶у鏁板緋誨崥澹紝浣犲彧瑕佺炕緲誨墠鑻忚仈鐨勫ぇ瀛︽暟瀛︽暀鏉愬氨鐭ラ亾浜嗭紝鑳藉鍦ㄨ帿澶ф嬁鍒版暟瀛﹀崥澹殑錛屾牴鏈氨鏄姭鐫浜虹毊鐨勫鏄熼珮絳夋櫤鎱с傝屾垜浠紪鍐欏湴鐞冧笂鐨勭▼搴忥紝鍙兘榪樻槸搴旇浠ュ湴鐞冧漢鐨勮鐐逛負涓匯?/p>
1. 閲嶅涓閬嶅璞¤寖寮忕殑涓や釜鍩烘湰瑙傚康錛?br>紼嬪簭鏄敱瀵硅薄緇勬垚鐨勶紱 璇鋒敞鎰忥紝榪欎袱涓蹇典笌鍚庢潵鎴戜滑鐔熺煡鐨勯潰鍚戝璞′笁瑕佺礌“灝佽銆佺戶鎵褲佸鎬?#8221;鏍規(guī)湰涓嶅湪涓涓眰闈笂錛屽掓槸涓庡啀鍚庢潵鐨?#8220;緇勪歡銆佹帴鍙?#8221;紲炲悎銆?/p>
2. 涓栫晫涓婄涓涓潰鍚戝璞¤璦鏄疭imula-67錛岀浜屼釜闈㈠悜瀵硅薄璇█鏄疭malltalk-71銆係malltalk鍙楀埌浜哠imula-67鐨勫惎鍙戯紝鍩烘湰鍑哄彂鐐圭浉鍚岋紝浣嗕篃鏈夐噸澶х殑涓嶅悓銆傚厛璇寸浉鍚屼箣澶勶紝Simula鍜孲malltalk閮界鎵夸笂榪板璞¤寖寮忕殑涓や釜鍩烘湰瑙傚康錛屼負浜嗘柟渚垮璞$殑鏋勯狅紝涔熼兘寮曞叆浜嗙被銆佺戶鎵跨瓑姒傚康銆備篃灝辨槸璇達紝綾匯佺戶鎵胯繖浜涙満鍒舵槸涓轟簡瀹炵幇瀵硅薄鑼冨紡鍘熷垯鑰屾瀯閫犲嚭鏉ョ殑絎簩浣嶇殑銆佸伐鍏鋒х殑鏈哄埗錛岄偅涔堜負浠涔堝悗鏉ヨ繖浜涚浜屼綅鐨勪笢瑗跨浜嗕富浣嶏紝鍚庨潰鎴戜細鍐嶆潵鍒嗘瀽銆傝孲imula鍜孲malltalk鏈閲嶅ぇ鐨勪笉鍚岋紝灝辨槸Simula鐢ㄦ柟娉曡皟鐢ㄧ殑鏂瑰紡鍚戝璞″彂閫佹秷鎭紝鑰孲malltalk鏋勯犱簡鏇寸伒媧誨拰鏇寸函綺圭殑娑堟伅鍙戦佹満鍒躲?/p>
鍏蜂綋鐨勮錛屽悜涓涓猄imula瀵硅薄涓彂閫佹秷鎭紝灝辨槸璋冪敤榪欎釜瀵硅薄鐨勪竴涓柟娉曪紝鎴栬呯О鎴愬憳鍑芥暟銆傞偅涔堜綘鎬庝箞鐭ラ亾鑳藉鍦ㄨ繖涓璞′笂璋冪敤榪欎釜鎴愬憳鍑芥暟鍛紵鎴栬呰錛屼綘鎬庝箞鐭ラ亾鑳藉鍚戣繖涓璞″彂閫佹煇涓秷鎭憿錛熻繖灝辮姹備綘蹇呴』紜繚榪欎釜瀵硅薄鍏鋒湁鍚堥傜殑綾誨瀷錛屼篃灝辨槸璇達紝浣犲緱鍏堢煡閬撳摝榪欎釜瀵硅薄鏄粈涔堬紝鎵嶈兘鍚戝畠鍙戞秷鎭傝屾秷鎭殑瀹炵幇鏂瑰紡琚洿鎺ュ鐞嗕負鎴愬憳鍑芥暟璋冪敤錛屾垨铏氬嚱鏁拌皟鐢ㄣ?/p>
鑰孲malltalk鍦ㄨ繖涓鐐逛笂鍋氫簡涓涓巻鍙叉х殑璺ㄨ秺錛屽畠瀹炵幇浜嗕竴涓笌鐩爣瀵硅薄鏃犲叧鐨勬秷鎭彂閫佹満鍒訛紝涓嶇閭d釜瀵硅薄鏄皝錛屼篃涓嶇瀹冩槸涓嶆槸鑳芥紜殑澶勭悊涓涓秷鎭紝浣滀負鍙戦佹秷鎭殑瀵硅薄鏉ヨ錛屽彲浠ユ鏃犻【蹇屽湴鎶撲綇涓涓璞″氨鍙戞秷鎭繃鍘匯傛帴鍒版秷鎭殑瀵硅薄錛岃灝濊瘯鐞嗚В榪欎釜娑堟伅錛屽茍鏈鍚庤皟鐢ㄨ嚜宸辯殑榪囩▼鏉ュ鐞嗘秷鎭傚鏋滆繖涓秷鎭兘琚鐞嗭紝閭d釜瀵硅薄鑷劧浼氬鐞嗗ソ錛屽鏋滀笉鑳借澶勭悊錛孲malltalk緋葷粺浼氬悜娑堟伅鐨勫彂閫佽呭洖浼犱竴涓猟oesNotUnderstand娑堟伅錛屼簣浠ラ氱煡銆傚璞′笉鐢ㄥ叧蹇冩秷鎭槸濡備綍浼犻掔粰鍙︿竴涓璞$殑錛屼紶閫掕繃紼嬭鍒嗙鍑烘潵錛堣屼笉鏄儚Simula閭f牱鏄庣‘鍦拌浠ユ垚鍛樺嚱鏁拌皟鐢ㄧ殑鏂瑰紡瀹炵幇錛夛紝鍙互鏄湪鍐呭瓨涓鍒訛紝涔熷彲浠ユ槸榪涚▼闂撮氳銆傚埌浜哠malltalk-80鏃訛紝娑堟伅浼犻掔敋鑷沖彲浠ヨ法瓚婄綉緇溿?/p>
涓轟簡鏂逛究鍚庨潰鐨勮璁猴紝涓嶅Θ鎶婃簮鑷猄imula鐨勬秷鎭満鍒剁О涓?#8220;闈欐佹秷鎭満鍒?#8221;錛屾妸婧愯嚜Smalltalk鐨勬秷鎭満鍒剁О涓?#8220;鍔ㄦ佹秷鎭満鍒?#8221;銆?/p>
Simula涓嶴malltalk涔嬮棿瀵逛簬娑堟伅鏈哄埗鐨勪笉鍚岄夋嫨錛屼富瑕佹槸鍥犱負涓よ呬簬鐢ㄩ斻傚墠鑰呮槸鐢ㄤ簬浠跨湡紼嬪簭寮鍙戯紝鑰屽悗鑰呯敤浜庡浘褰㈢晫闈㈢幆澧冩瀯寤猴紝鐪嬩笂鍘誨悇鑷悎鎯呭悎鐞嗐傜劧鑰岋紝灝辨槸榪欎箞涓鐐圭畝鍗曠殑鍖哄埆錛屽嵈閫犳垚浜嗗法澶х殑鍘嗗彶鍚庢灉銆?/p>
3. 鍒頒簡1980騫翠唬錛孋++鍑虹幇浜嗐侭jarne Stroustrup鍦ㄥ崥澹湡闂存繁鍏ョ爺絀惰繃Simula錛岄潪甯告璧忓叾鎬濇兂錛屼簬鏄氨鍦–璇█璇硶鐨勫熀紜涔嬩笂錛屽嚑涔庢妸Simula鐨勬濇兂鐓ф惉榪囨潵錛屽艦鎴愪簡鏈鍒濈殑C++銆侰++闂笘浠ヤ箣鍒濓紝涓昏鐢ㄤ簬瑙e喅瑙勬ā紼嶅ぇ鐨勪紶緇熺被鍨嬬殑緙栫▼闂錛岃繀閫熷彇寰椾簡宸ㄥぇ鐨勬垚鍔燂紝涔熻瘉鏄庝簡瀵硅薄鑼冨紡鏈韓鎵鍏鋒湁鐨勫▉鍔涖?/p>
澶х害鍦ㄥ悓鏈燂紝Brad Cox鏍規(guī)嵁Smalltalk鐨勬濇兂璁捐浜哋bjective-C錛屽彲鏄敱浜庡叾璇硶鎬紓錛屾病鏈夋祦琛岃搗鏉ャ傚彧鏈塖teve Jobs榪欑鍏鋒湁紱呭畻緹庡閴磋祻鍔涚殑涓栧楂樹漢錛屾妸瀹冨涓虹懓瀹濓紝涓?988騫磋繛閿呮妸Objective-C鐨勫洟闃熷拰浜у搧涓鍙f皵涔頒簡涓嬫潵銆?/p>
4. 灝卞湪鍚屼竴鏃舵湡錛孏UI鎴愪負鐑棬銆傝櫧鐒禛UI鐨勬湰璐ㄦ槸瀵硅薄鑼冨瀷鐨勶紝浣嗘槸褰撴椂錛?980騫翠唬涓湡錛夌殑闈㈠悜瀵硅薄璇█錛屽寘鎷珻++璇█錛岃繕榪滀笉鎴愮啛錛屽洜姝ゆ渶鍒濈殑GUI緋葷粺鏃犱竴渚嬪鏄嬌鐢–鍜屾眹緙栬璦寮鍙戠殑銆傛垨鑰呰錛屾渶鍒濈殑GUI寮鍙戣呯‖鏄敤鎶借薄綰у埆鏇翠綆鐨勮璦鏋勯犱簡涓涓潰鍚戝璞$郴緇熴傜啛鎮(zhèn)塛in32 SDK寮鍙戠殑浜猴紝搴旇鐭ラ亾鎴戝湪璇翠粈涔堛?/p>
5. 褰撴椂寰堝浜轟互涓猴紝濡傛灉C++鏇存垚鐔熶簺錛岀洿鎺ョ敤C++鏉ユ瀯閫燱indows緋葷粺浼氬ぇ澶у湴瀹規(guī)槗銆備篃鏈変漢瑙夊緱錛屽敖綆indows緋葷粺鏈韓浣跨敤C鍐欑殑錛屼絾鏄叾闈㈠悜瀵硅薄鐨勬湰璐ㄤ笌C++鏇村鍚堬紝鎵浠ュ湪鍏跺熀紜涓婂寘瑁呬竴涓狢++鐨凣UI framework涓瀹氭槸杞昏屾槗涓俱傚彲鏄竴鍔ㄦ墜浜轟滑灝卞彂鐜幫紝瀹屽叏涓嶆槸閭d箞鍥炰簨銆傜敤C++寮鍙慦indows妗嗘灦闅懼緱瑕佹銆備負浠涔堝憿錛熶富瑕佸氨鏄疻indows緋葷粺涓殑娑堟伅鏈哄埗瀹為檯涓婃槸鍔ㄦ佺殑錛屼笌C++鐨勯潤鎬佹秷鎭満鍒舵牴鏈厤鍚堜笉鍒頒竴璧峰幓銆傚湪Windows閲岋紝浣犲彲浠ュ悜浠諱綍涓涓獥鍙e彂閫佹秷鎭紝榪欎釜紿楀彛鑷繁浼氬湪鑷繁鐨剋ndproc閲屾潵澶勭悊榪欎釜娑堟伅錛屽鏋滃畠澶勭悊涓嶄簡錛屽氨浜ょ粰default window/dialog proc鍘誨鐞嗐傝屽湪C++閲岋紝浣犺鍚戜竴涓獥鍙e彂娑堟伅錛屽氨寰楃‘淇濊繖涓獥鍙h兘澶勭悊榪欎釜娑堟伅錛屾垨鑰呰錛屽叿鏈夊悎閫傜殑綾誨瀷銆傝繖鏍蜂竴鏉ョ殑璇濓紝灝變細瀵艱嚧涓涓敊緇煎鏉傜殑紿楀彛綾誨眰嬈$粨鏋勶紝鏃犳硶瀹炵幇銆傝屽鏋滀綘瑕佽鎵鏈夌殑紿楀彛綾婚兘鑳藉鐞嗘墍鏈夊彲鑳界殑娑堟伅錛屼笖涓嶈榪欐牱鍦ㄩ昏緫涓婂氨琛屼笉閫氾紙鐢ㄦ埛瀹氫箟鐨勬秷鎭庝箞澶勭悊錛燂級錛屽崟鍦ㄥ疄鐜頒笂灝變笉鍙帴鍙椻斺斾負涓涓皬灝忕殑涓嶅悓灝卞緱鍒涢犱竴涓柊鐨勭獥鍙g被錛屾瘡涓涓皬灝忕殑紿楀彛綾婚兘瑕佽儗涓婁竴涓杈炬暟鐧鵑」鐨剉-table錛岃屽叾涓彲鑳?9%鐨勯」閮芥槸嫻垂錛屼笉瑕佽鍦ㄥ綋鏃訛紝灝辨槸鍦ㄤ粖澶╋紝鍐呭瓨鏁伴噺闈炲父涓板瘜鐨勬椂鍊欙紝濡傛灉姣忎竴涓狦UI紼嬪簭閮借繖涔堟悶錛岀敤鎴蜂篃鍚冧笉娑堛?/p>
6. 瀹為檯涓奀++鐨勯潤鎬佹秷鎭満鍒惰繕寮曡搗浜嗘洿娣變弗閲嶇殑闂鈥斺旀壄鏇蹭簡浜轟滑瀵歸潰鍚戝璞$殑鐞嗚В銆傛棦鐒跺繀欏昏鍏堢煡閬撳璞$殑綾誨瀷錛屾墠鑳藉悜瀵硅薄鍙戞秷鎭紝閭d箞“綾?#8221;榪欎釜姒傚康灝辯壒鍒噸瑕佷簡錛岃屽璞″彧涓嶈繃鏄被榪欎釜妯″瓙閲岄犲嚭鏉ョ殑涓滆タ錛屽弽鑰屼笉閲嶈銆傛笎娓愮殑錛?#8220;闈㈠悜瀵硅薄緙栫▼”鍙樻垚浜?#8220;闈㈠悜綾葷紪紼?#8221;錛?#8220;闈㈠悜綾葷紪紼?#8221;鍙樻垚浜?#8220;鏋勯犵被緇ф壙鏍?#8221;銆傛斁鍦ㄧ溂鍓嶇殑椴滄椿鐨勫璞℃椿鍔ㄤ笉閲嶈浜嗭紝鍙嶈屾槸鍏惰儗鍚庣殑闈欐佺被鍨嬬郴緇熸垚涓哄叧閿?#8220;灝佽銆佺戶鎵?#8221;榪欎簺絎簩絳夌殑鐗規(guī)э紝鍠у澶轟富錛屼卡鐒舵垚浜嗛潰鍚戝璞$殑瑕佺礌銆傛瘡涓▼搴忓憳浼間箮閮借鍏堟垚涓洪鍩熶笓瀹訛紝鐒跺悗鎴愪負棰嗗煙鍒嗙被瀛︿笓瀹訛紝鐒跺悗鏋勯犱竴涓畬鏁寸殑緇ф壙鏍戯紝鐒跺悗鎵嶈兘new鍑哄璞★紝璁╃▼搴忚窇璧鋒潵銆傛鏄洜涓鴻繖涓繃紼嬪お婕暱錛屽お鍥伴毦錛屽啀鍔犱笂C++鏈韓鐨勫鏉傚害灝卞緢澶э紝鎵浠++鍑虹幇榪欎箞澶氬勾錛岀湡姝e牚縐扮粡鍏哥殑闈㈠悜瀵硅薄綾誨簱鍜屾鏋訛紝鍑犱箮灞堟寚鍙暟銆傚緢澶氭祦琛岀殑搴擄紝姣斿MFC銆乮ostream錛岄兘鏆撮湶鍑轟笉灝戦棶棰樸備竴鑸▼搴忓憳鎬昏寰楁槸鑷繁鐨勬按騫充笉澶燂紝浜庢槸涓嬫洿澶у姛澶幓緇冨墤銆傛畩涓嶇煡鏍規(guī)湰涓婃槸鏂瑰悜閿欎簡錛岃劚紱諱簡瀵硅薄鑼冨紡鐨勬湰璐紝浼佸浘鐢ㄩ潤鎬佸垎綾繪硶鏉ュ鐜板疄涓栫晫寤烘ā錛屽幓鍒葷敾鍙樺寲涓囧崈鐨勫姩鎬佷笘鐣屻傝繖涔堥毦鐨勪簨錛屼綘姘村鉤鍐嶉珮涔熷緢闅懼仛濂姐?/p>
鍙互浠庝竴涓叿浣撶殑渚嬪瓙鏉ョ悊瑙h繖涓亾鐞嗭紝姣斿鍦ㄤ竴涓狦UI緋葷粺閲岋紝涓涓?Push Button 鐨勮璁¢棶棰樸備簨瀹炰笂鍦ㄤ竴涓疄闄呯殑紼嬪簭閲岋紝涓涓?push button 鍒板簳“鏄笉鏄?#8221;涓涓?button錛岃繘鑰屾槸涓嶆槸涓涓?window/widget錛屽茍涓嶉噸瑕侊紝鏈川涓婃垜鏍規(guī)湰涓嶅叧蹇冨畠鏄粈涔堬紝瀹冧粠灞炰簬鍝竴涓被錛屽湪緇ф壙鏍戦噷澶勪簬浠涔堜綅緗紝鍙閭i噷鏈夎繖涔堜竴涓笢瑗匡紝鎴戝彲浠ョ偣瀹冿紝鐐瑰畬浜嗗彲浠ュ彂鐢熺浉搴旂殑鏁堟灉錛屽氨鍙互浜嗐傚彲鏄疭imula –> C++ 鎵榧撳姳鐨勯潰鍚戝璞¤璁¢鏍鹼紝闈炶涓婃潵灝辨兂娓呮錛宎 Push Button is-a Button, a Button is-a Command-Target Control, a Command-Target Control is-a Control, a Control is-a Window. 鎶婅繖涓鍦堥兘鎯抽忓交涔嬪悗錛屾墠鑳?new 涓涓?Push Button錛岀劧鍚庢墠鑳借瀹冨伐浣溿傝繖灝卞艦鑰屼笂瀛︿簡錛岃繖灝辮劚紱誨疄闄呬簡銆傛墍浠ュ緢闅懼仛濂姐備綘鐪嬪埌 MFC 鐨勭被緇ф壙鏍戯紝瑙夊緱璁捐鑰呭お鐗涗簡錛岃兘鎶婅繖浜涘眰嬈℃蹇甸兘鎯蟲竻妤氾紝鑷繁鐨勬按騫寵繕涓嶅錛岃繕寰椾慨鐐箋傚疄闄呬笂鍛紝榪欎釜璁捐鏄粡榪囨暟涓嶆竻鐨勫け璐ュ拰閽辯(鍑烘潵銆佺牳鍑烘潵鐨勶紝MFC鐨勫墠韜?Afx 涓嶆槸灝卞け璐ヤ簡鍚楋紵1995騫磋繕鏈変竴涓彨鍋?Taligent 鐨勫ぇ欏圭洰錛屽彫闆嗕簡鍖呮嫭 Eric Gamma 鍦ㄥ唴鐨勪竴澶у爢鐗涗漢錛岃鐢–++鍋氫竴涓竴緇熷ぉ涓嬬殑application framework錛屾渶鍚庝篃浠ユ儴璐ュ憡緇堬紝榪炲叕鍙擱兘鍊掗棴浜嗭紝CEO杞︾ジ韜骸錛岀墰浜轟滑鎮(zhèn)夋暟閬f暎銆傞檮甯﹁涓涓嬶紝榪欎釜Taligent欏圭洰鏄負浜嗚窡NextSTEP鍜孧icrosoft Cairo绔炰簤錛屽墠鑰呯敤Objective-C緙栧啓錛屽悗鏉ュ彂灞曚負Cocoa錛屽悗鑰呯敤浼犵粺鐨刉in32 + COM浣滀負鍩虹鏋舵瀯錛屽悗鏉ュ彂灞曚負Windows NT銆傝孫bjective-C鍜孋OM錛屾伆鎭板氨鍦ㄥ姩鎬佹秷鎭垎媧炬柟闈紝涓嶤++榪ョ劧涓嶅悓銆傚悗闈㈣繕浼氳皥鍒般?/p>
瀹㈣鍦拌錛?#8220;闈㈠悜綾葷殑璁捐”騫朵笉鏄病鏈夋剰涔夈傛潵婧愪簬瀹炶返鍙堥珮浜庡疄璺電殑鎶借薄鍜屾蹇碉紝寰寰鑳芥洿鏈夊姏鍦版妸鎻′綇鐜板疄涓栫晫鐨勬湰璐紝姣斿MVC鏋舵瀯錛屽氨鏄繖鏍風殑鏈夊姏鐨勬娊璞°備絾鏄繖縐嶆娊璞★紝搴旇鏄潵婧愪簬闀挎湡鏈浣沖疄璺電殑鎬葷粨鍜屾彁楂橈紝鑰屼笉鏄潰瀵歸棶棰樻椂涓昏鐨勮В鍐蟲濊礬銆傝繃浜庡己璋冭繖縐嶆娊璞★紝鏃犲紓浜庡亣瀹氱▼搴忓憳鍚勪釜閮芥槸鍝插瀹訛紝鍏鋒湁瀵圭幇瀹炰笘鐣屽噯紜屾繁鍒葷殑鎶借薄鑳藉姏錛屽綋鐒舵槸涓嶇鍚堝疄闄呮儏鍐電殑銆傜粨鏋滃憿錛屽垰瀛︿範闈㈠悜瀵硅薄娌″嚑澶╃殑紼嬪簭鍛橈紝瀵圭溂鍓嶉矞媧葷殑瀵硅薄涓栫晫瑙嗚屼笉瑙侊紝涓涓釜閮界厼鏈変粙浜嬪湴鍘繪悶鍝插鍐ユ兂錛屼紒鍥捐秺榪囩幇瀹炰笘鐣岋紝鍘繪娊璞″嚭鍏惰儗鍚庢湰璐紝褰撶劧璐ュ緱寰堟儴銆?/p>
鍏跺疄C++闂笘涔嬪悗涓嶄箙錛岃繖涓棶棰樺氨鏆撮湶鍑烘潵浜嗐傜涓涓狢++緙栬瘧鍣?Cfront 1.0 鏄崟緇ф壙錛岃屽埌浜?Cfront 2.0錛屽姞鍏ヤ簡澶氱戶鎵褲備負浠涔堬紵灝辨槸鍥犱負浣跨敤涓漢浠彂鐜伴昏緫涓婁技涔庡畬緹庣殑闈欐佸崟緇ф壙鍏崇郴錛岀鍒板鏉傜伒媧葷殑鐜板疄涓栫晫錛屽氨鐮寸喚鐧懼嚭鈥斺旇潤铦犳槸楦熶篃鏄吔錛屾按涓婇鏈鴻兘椋炰篃鑳芥父錛屽畠浠濡備綍褰掔被鍛紵鏈潵榪欏簲璇ヤ績浣垮ぇ瀹跺弽鎬濈戶鎵胯繖涓満鍒舵湰韜紝浣嗘槸閭d釜鏃跺欏叏涓栫晫闄峰叆緇ф壙鐙傜儹錛屼簬鏄氨寮濮嬬粰緇ф壙鎵撹ˉ涓侊紝鍔犲叆澶氱戶鎵匡紝榪涜屽姞鍏ヨ櫄緇ф壙錛屻傚埌浜嗚櫄緇ф壙錛屾槑鐪間漢涓鐪嬩究鐭ワ紝榪欏彧鏄竴涓娉曡ˉ涓侊紝鏄負浜嗛冮伩鑱岃矗鑰屽埗閫犵殑涓鍧楁棤鐢ㄧ殑閬緸甯冿紝瀹冨凡緇忓畬鍏ㄥ凡緇忚劚紱誨疄璺典簡鈥斺旀湁璋佸湪浜嬪墠鑳藉鍒ゆ柇鏄惁搴旇瀵瑰熀綾昏繘琛岃櫄緇ф壙鍛紵 鍒頒簡1990騫翠唬涓湡錛岄棶棰樺凡緇忓崄鍒嗘槑鏄俱俇ML涓湁涓涓璞℃椿鍔ㄥ浘錛屽叾鎻忚堪鐨勫氨鏄繍琛屾椂瀵硅薄涔嬮棿鐩鎬簰浼犻掓秷鎭殑妯″瀷銆?994騫碦obert C. Martin鍦ㄣ奜bject-Oriented C++ Design Using Booch Method銆嬩腑錛屾浘寤鴻闈㈠悜瀵硅薄璁捐浠庡璞℃椿鍔ㄥ浘鍏ユ墜錛岃屼笉鏄粠綾誨浘鍏ユ墜銆傝?995騫村嚭鐗堢殑緇忓吀浣滃搧銆奃esign Patterns銆嬩腑錛屽緩璁紭鍏堣冭檻緇勫悎鑰屼笉鏄戶鎵匡紝榪欎篃鏄敖浜虹殕鐭ョ殑浜嬫儏銆傝繖浜涜抗璞¤〃鏄庯紝鍦ㄩ偅涓椂鍊欙紝闈㈠悜瀵硅薄紺懼尯閲岀殑鎬濇兂棰嗚浠紝宸茬粡鎰忚瘑鍒?#8220;闈㈠悜綾葷殑璁捐”騫朵笉濂界敤銆傚彧鍙儨浠栦滑鐨勯潻鍛界簿紲炶繕涓嶅銆?/p>
7. 浣犲彲鑳借闂紝Java 鍜?NET涔熸槸鐢ㄧ戶鎵垮叧緋葷粍緇囩被搴擄紝騫惰繘琛岃璁$殑鍟婏紝鎬庝箞閭d箞鎴愬姛鍛紵榪欓噷鏈変笁鐐瑰簲璇ユ敞鎰忋傜涓錛孋++鐨勯毦涓嶄粎浠呭湪浜庡叾闈欐佺粨鏋勪綋緋伙紝榪樻湁寰堝婧愪簬璇█璁捐涓婄殑鍖呰⒈錛屾瘮濡傚C鐨勫吋瀹癸紝姣斿娌℃湁鍨冨溇鏀墮泦鏈哄埗錛屾瘮濡傚鏁堢巼鐨勫己璋冿紝絳夌瓑銆備竴鏃︽妸榪欎簺鍖呰⒈涓㈡帀錛岃璁$殑闅懼害紜疄鍙互澶уぇ涓嬮檷銆傜浜岋紝Java鍜?NET鐨勬牳蹇冪被搴撴槸鍦–++鍗佸嚑騫存垚鍔熷拰澶辮觸鐨勭粡楠屾暀璁熀紜涔嬩笂錛岀粨鍚圕OM浣撶郴浼樼偣璁捐瀹炵幇鐨勶紝鑷劧瑕佸ソ涓婁竴澶у潡銆備簨瀹炰笂錛屽湪Java鍜?NET鏍稿績綾誨簱鐨勮璁′腑寰堝鍦版柟錛屼綋鐜扮殑鏄熀浜庢帴鍙g殑璁捐錛屽拰鐪熸鐨勫熀浜庡璞$殑璁捐銆傛湁浜嗚繖涓や釜涓昏绔欏彴錛?#8220;闈㈠悜綾葷殑璁捐”涓嶈兘鍠у澶轟富錛屼篃鑳藉彂鎸ヤ竴浜涘ソ鐨勪綔鐢ㄣ傜涓夛紝濡傚悗鏂囨寚鍑猴紝Java鍜?NET涓垎鍒C++鏈澶х殑闂鈥斺旂己灝戝璞$駭鍒殑delegate鏈哄埗鍋氬嚭浜嗚嚜宸辯殑鍥炲簲錛岃繖灝卞ぇ澶у譏琛ヤ簡鍘熸潵鐨勯棶棰樸?/p>
灝界濡傛錛孞ava榪樻槸娌炬煋涓婁簡“闈㈠悜綾昏璁?#8221;鐨勭檶鐥囷紝鍩虹綾誨簱閲屽氨鏈夊緢澶氭灦搴婂彔灞嬬殑璁捐錛岃孞2EE/Java EE褰撲腑錛岃繖縐嶅艦鑰屼笂瀛︾殑璁捐涔熷緢鏅亶錛屾墍浠ヤ篃寮曞彂浜嗗ソ鍑犳杞婚噺鍖栫殑榪愬姩銆傝繖鏂歸潰鎴戝茍涓嶆槸澶噦錛屽彲鑳介渶瑕佺湡姝g殑Java楂樻墜鍑烘潵鐜拌韓璇存硶銆傛垜瀵笿ava鐨勭湅娉曚互鍓嶅氨璁茶繃鈥斺斿鉤鍙板拰璇█鏍稿績闈炲父濂斤紝浣嗛姘斾笉濂斤紝宕囧皻鍗庝附綣佸鐨勮璁★紝瑁呯墰閫肩殑浜哄お澶氥?/p>
鑷充簬.NET錛屾垜鍚檲姒曚粙緇嶈繃錛屽湪璁捐.NET鐨勬椂鍊欙紝寰蔣鍐呴儴瀵逛簬鏄惁鍏佽緇ф壙鐖嗗彂浜嗛潪甯告縺鐑堢殑浜夎銆傚緢澶氳祫娣遍珮浜洪兘寮虹儓鍙嶅緇ф壙銆傝嚦浜庢渶鍚庡紩鍏ョ戶鎵匡紝寰堝ぇ紼嬪害涓婃槸钀ラ攢闇瑕佸帇鍊掍簡鎶鏈悊鎬с傚敖綆″姝わ紝鐢變簬鏈塁OM鐨勫熀紜錛屽張瀹炵幇浜嗛潪甯稿交搴曠殑delegate錛屾墍浠?.NET 鐨勮璁℃按騫寵繕鏄緢楂樼殑銆傚畠鐨勪富瑕侀棶棰樹笉鍦ㄨ繖錛屽湪浜庡お鎬ヤ簬姹傝儨錛屾洿鏂伴熷害澶揩錛屽熀紜涓嶇墷銆傚綋鐒訛紝鏍規(guī)湰闂榪樻槸寰蔣娌℃湁鑳藉鍦╓eb鍜孧obile棰嗗煙閲屽崰鍒板澶х殑浼樺娍錛屼篃灝變嬌寰?NET娌℃湁鐢ㄦ涔嬪湴銆?/p>
8. COM銆侰OM鐨勮涔夋槸錛岃蔣浠舵槸鐢盋OM Components緇勬垚錛宑omponents涔嬮棿褰兼閫氳繃鎺ュ彛鐩鎬簰閫氳銆傝繖鏄惁璁╀綘鍥炴兂璧鋒湰鏂囧紑綃囨墍鎻愬嚭鐨勫璞¤寖鍨嬬殑涓や釜鍩烘湰鍘熷垯錛熸湁瓚g殑鏄紝鍦–OM鐨勬湳璇噷錛?#8220;COM Component ” 涓?#8220;object ”閫氬亣錛岃繖灝變嬌COM鐨勫績鎬濇槶鐒惰嫢鎻簡銆侱on Box鍦‥ssential COM閲屽紑綃囧氨璇達紝COM鏄洿濂界殑C++錛屼簨瀹炰笂灝辨槸鍛婅瘔澶у錛屽艦鑰屼笂瀛︾殑“闈㈠悜綾昏璁?#8221;涓嶅ソ浣匡紝榪樻槸鍥炲埌瀵硅薄鍚с?/p>
鐢–OM寮鍙戠殑鏃跺欙紝涓涓粍浠?#8220;鏄粈涔?#8221;涓嶉噸瑕侊紝瀹冨叿鏈変粈涔堟帴鍙o紝涔熷氨鏄錛岃兘澶熷瀹冨彂浠涔堟秷鎭紝鎵嶆槸閲嶈鐨勩備綘鍙互鐢↖Unknown::QueryInterface闂粍浠惰兘瀵瑰摢涓緇勬秷鎭綔鍑哄弽搴斻傚悜緇勪歡鍒嗘淳娑堟伅涔熶笉涓瀹氳琚粦瀹氬湪鏂規(guī)硶璋冪敤涓婏紝濡傛灉瀹炵幇浜?IDispatch錛岃繕鍙互瀹炵幇“鑷姩鍖?#8221;璋冪敤錛屼篃灝辨槸COM鏈閲岀殑 Automation錛岃岄氳繃 鍒楅泦錛坢ashal錛夛紝鍙互璺ㄨ繘紼嬨佽法緗戠粶鍚戝彟涓緇勪歡鍙戦佹秷鎭紝閫氳繃 moniker錛屽彲浠ュ湪鍒嗗竷寮忕郴緇熼噷瀹氫綅鍜屽彂鐜扮粍浠躲傚鏋滀綘鎶辯潃“瀵硅薄鈥斺旀秷鎭?#8221;鐨勮蹇靛幓鐪婥OM鐨勮璁★紝灝變細鎰忚瘑鍒幫紝鏁翠釜COM浣撶郴灝辨槸鐢ㄨ鑼冨浣曞仛瀵硅薄錛屽浣曞彂娑堟伅鐨勩傛垨鑰呮洿鐩寸櫧涓鐐癸紝COM灝辨槸鐢–/C++紜槸妯℃嫙鍑轟竴涓猄malltalk銆傝屼笖COM鐨勬蹇典笘鐣岄噷娌℃湁緇ф壙錛屽氨鍏剁函媧佹ц岃█錛屾瘮Smalltalk榪楽malltalk銆傚湪瀵硅薄娉涘瀷涓婏紝COM杈懼埌浜嗕竴涓珮宄幫紝棰嗗厛浜庨偅涓椂浠o紝鐢氳嚦浜庢瘮瀹冪殑緇т換.NET榪樿綰磥銆?/p>
COM鐨勪富瑕侀棶棰樻槸瀹冪殑瀛︿範闅懼害鍜屽畨鍏ㄩ棶棰橈紝鑰屼笖錛屽畠榪囦簬榪芥眰綰磥鎬э紝瀹屽叏鏀懼純浜?#8220;闈㈠悜綾昏璁?#8221; 鐨勬満鍒訛紝鏄懼緱鏈夌偣榪囥?/p>
9. 濂藉儚鏈夌偣鎵繙浜嗭紝鍏跺疄榪樻槸鍦ㄨ姝d簨銆備笂闈㈣鍒扮敱浜嶤++鐨勯潤鎬佹秷鎭満鍒訛紝瀵艱嚧浜嗗艦鑰屼笂瀛︾殑“闈㈠悜綾葷殑璁捐”錛岀ジ瀹蟲棤絀楓備絾瀹為檯涓婏紝C++鏄湁涓涓ˉ鏁戞満浼氱殑錛岄偅灝辨槸瀹炵幇瀵硅薄綰у埆鐨刣elegate鏈哄埗銆傚榪?NET鐨勪漢錛屼竴鍚琩elegate榪欎釜璇嶅氨鐭ラ亾鏄粈涔堟剰鎬濓紝浣咼ava閲屾病鏈夊搴旀満鍒躲傚湪C++鐨勬湳璇綋緋婚噷錛屾墍璋撳璞$駭鍒玠elegate錛屽氨鏄竴涓璞″洖璋冩満鍒躲傞氳繃delegate錛屼竴涓璞鍙互鎶婁竴涓壒瀹氬伐浣滐紝姣斿澶勭悊鐢ㄦ埛鐨勯紶鏍囦簨浠訛紝濮旀墭緇欏彟涓涓璞鐨勪竴涓柟娉曟潵瀹屾垚銆侫涓嶅繀鐭ラ亾B鐨勫悕瀛楋紝涔熶笉鐢ㄧ煡閬撳畠鐨勭被鍨嬶紝鐢氳嚦閮戒笉闇瑕佺煡閬揃鐨勫瓨鍦紝鍙姹侭瀵硅薄鍏鋒湁涓涓鍚嶆紜殑鏂規(guī)硶錛屽氨鍙互閫氳繃delegate鎶婂伐浣滀氦緇橞鐨勮繖涓柟娉曟潵鎵ц銆傚湪C璇█閲岋紝榪欎釜鏈哄埗鏄氳繃鍑芥暟鎸囬拡瀹炵幇鐨勶紝鎵浠ュ緢鑷劧鐨勶紝鍦–++閲岋紝鎴戜滑甯屾湜閫氳繃鎸囧悜鎴愬憳鍑芥暟鐨勬寚閽堟潵瑙e喅綾諱技闂銆?/p>
鐒惰屽氨鍦ㄨ繖涓棶棰樹笂錛孋++璁╀漢鎵艱厱鐥涙儨銆?/p>
榪欐鍐呭澶ц嚧璁茬殑鏄叧浜庢ā鏉夸腑鐨勫懡鍚嶅喅璁細“scope of the template definition”涓?#8220;scopy of the template instantition”銆?/span>
鍧︾櫧鐨勮鎴戞槸絎竴嬈$湅鍒拌繖涓鐭ヨ瘑鐐癸紝鍦ㄤ笂鏈洪獙璇佸悗鍙堝洖鎯熾奀++ Primer銆?4th涓彲鏇炬湁鎻愬強榪囷紝鍚庢潵鍙戠幇4th涓病鏈夛紝鍊掓槸3rd涓湁涓撻棬鐨勪竴灝忚妭涓撻棬闄堣堪浜嗕笅銆?br />
鍚庢潵鎴戝湪銆婃繁搴︽帰绱++瀵硅薄妯″瀷銆嬩功涓叧浜庢ā鏉夸腑鍛藉悕鍐寵鍐呭鐨勬梺杈瑰啓涓嬩簡榪欐牱涓孌佃瘽錛?br />
浠婂ぉ鎵嶅彂鐜拌繕鏈夎繖涔堜釜涓滆タ銆傛垜鍙兘鎵胯鑷繁鐨勬棤鐭ヤ笌C++鐨勫彉鎬侊紝闈㈠榪欎竴鐭ヨ瘑鐐廣?br /> 2012.5.2 澶?br />
]]>Lambda 琛ㄨ揪寮?/h2>
鏉ョ湅涓鏁版煇涓瓧絎﹀簭鍒椾腑鏈夊嚑涓ぇ鍐欏瓧姣嶇殑渚嬪瓙錛?br />
鍏朵腑 [&Uppercase] 涓殑 & 鐨勬剰涔夋槸 lambda 鍑芥暟浣撹鑾峰彇涓涓?Uppercase 寮曠敤錛屼互渚胯兘澶熸敼鍙樺畠鐨勫鹼紝濡傛灉娌℃湁 &錛岄偅灝?Uppercase 灝嗕互浼犲肩殑褰㈠紡浼犻掕繃鍘匯?鑷姩綾誨瀷鎺ㄥ鍜?decltype
榪欎釜鐗規(guī)у湪瀵硅薄鐨勭被鍨嬪緢澶у緢闀跨殑鏃跺欏緢鏈夌敤錛屽錛?br />
閭d釜榪唬鍣ㄥ彲浠ュ0鏄庝負錛?br />
C++11 涔熸彁渚涗簡浠庡璞℃垨琛ㄨ揪寮忎腑“淇樿幏”綾誨瀷鐨勬満鍒訛紝鏂扮殑鎿嶄綔絎?decltype 鍙互浠庝竴涓〃杈懼紡涓?#8220;淇樿幏”鍏剁粨鏋滅殑綾誨瀷騫?#8220;榪斿洖”錛?br /> 緇熶竴鐨勫垵濮嬪寲璇硶
榪樻湁絳夊彿褰㈠紡鐨勶細
瀵逛簬 POD 闆嗗悎錛屽張鍙互鐢ㄥぇ鎷彿錛?br />
鏈鍚庤繕鏈夋瀯閫犲嚱鏁扮殑鎴愬憳鍒濆鍖栵細
榪欎箞澶氬垵濮嬪寲褰㈠紡錛屼笉浠呰彍楦熶細鎼炲緱寰堝ご澶э紝楂樻墜涔熷悆涓嶆秷銆傛洿鎯ㄧ殑鏄?C++03 涓眳鐒朵笉鑳藉垵濮嬪寲 POD 鏁扮粍鐨勭被鎴愬憳錛屼篃涓嶈兘鍦ㄤ嬌鐢?new[] 鐨勬椂鍊欏垵濮?POD 鏁扮粍錛屾搷铔嬪晩錛丆++11 灝辯敤澶ф嫭鍙蜂竴緇熷ぉ涓嬩簡錛?br />
榪樻湁涓澶уソ浜嬪氨鏄浜庡鍣ㄦ潵璇達紝緇堜簬鍙互鎽嗚劚 push_back() 璋冪敤浜嗭紝C++11涓彲浠ョ洿瑙傚湴鍒濆鍖栧鍣ㄤ簡錛?br />
鑰岀被涓殑鏁版嵁鎴愬憳鍒濆鍖栦篃寰楀埌浜嗘敮鎸侊細
deleted 鍑芥暟鍜?defaulted 鍑芥暟
鍙仛 defaulted 鍑芥暟錛?default; 鎸囩ず緙栬瘧鍣ㄧ敓鎴愯鍑芥暟鐨勯粯璁ゅ疄鐜般傝繖鏈変袱涓ソ澶勶細涓鏄紼嬪簭鍛樿交鏉句簡錛屽皯鏁查敭鐩橈紝浜屾槸鏈夋洿濂界殑鎬ц兘銆?br /> 涓?defaulted 鍑芥暟鐩稿鐨勫氨鏄?deleted 鍑芥暟錛?br />
榪欒揣鏈変竴澶х敤閫斿氨鏄疄鐜?noncopyabe 闃叉瀵硅薄鎷瘋礉錛岃鎯崇姝㈡嫹璐濓紝鐢?=deleted 澹版槑涓涓嬩袱涓叧閿殑鎴愬憳鍑芥暟灝卞彲浠ヤ簡錛?br /> nullptr
鎵鏈夎窡鎸囬拡鏈夊叧鐨勫湴鏂歸兘鍙互鐢?nullptr錛屽寘鎷嚱鏁版寚閽堝拰鎴愬憳鎸囬拡錛?br /> 濮旀墭鏋勯犲嚱鏁?/h2>
#2 灝辨槸鎵璋撶殑濮旀墭鏋勯犲嚱鏁幫紝璋冪敤浜嗙湡姝g殑鏋勯犲嚱鏁?#1銆?鍙沖煎紩鐢?/h2>
榪欑鏂規(guī)寰堝偦寰堝ぉ鐪燂紝寰堟參錛屽洜涓洪渶瑕佺敵璇峰唴瀛橈紝鐒跺悗鎷瘋礉瀛楃錛岃?move 灝卞彧闇瑕佷氦鎹袱涓暟鎹垚鍛橈紝鏃犻』鐢寵銆侀噴鏀懼唴瀛樺拰鎷瘋礉瀛楃鏁扮粍錛?br />
瑕佸疄鐜版敮鎸?move 鐨勭被錛岄渶瑕佸0鏄?move 鏋勯犲嚱鏁板拰 move 璧嬪兼搷浣滅錛屽涓嬶細
C++11 鐨勬爣鍑嗗簱騫挎硾浣跨敤 move 璇箟錛屽緢澶氱畻娉曞拰瀹瑰櫒閮藉凡緇忎嬌鐢?move 璇箟浼樺寲榪囦簡銆?C++11 鐨勬爣鍑嗗簱
綰跨▼搴?/h3>
鏂扮殑鏅鴻兘鎸囬拡綾?/h3>
鏂扮殑綆楁硶
榪樻湁涓涓柊鐨?copy_n錛?br />
iota() 綆楁硶鍙互鐢ㄦ潵鍒涘緩閫掑搴忓垪錛屽畠鍏堟妸鍒濆艱祴鍊肩粰 *first錛岀劧鍚庣敤鍓嶇疆 ++ 鎿嶄綔絎﹀闀垮垵鍊煎茍璧嬪煎埌緇欎笅涓涓凱浠e櫒鎸囧悜鐨勫厓绱狅紝濡備笅錛?br />
鏄殑錛孋++11 浠嶇劧緙哄皯涓浜涘緢鏈夌敤鐨勫簱濡?XML API錛宻ocket錛孏UI銆佸弽灝?#8212;—浠ュ強鑷姩鍨冨溇鏀墮泦銆傜劧鑰岀幇鏈夌壒鎬у凡緇忚 C++ 鏇村畨鍏ㄣ侀珮鏁堬紙鏄殑錛屾晥鐜囨洿楂樹簡錛屽彲浠ュ弬瑙?Google 鐨? 鍩哄噯嫻嬭瘯緇撴灉http://www.itproportal.com/2011/06/07/googles-rates-c-most- complex-highest-performing-language/錛変互鍙婃洿鍔犳槗浜庡涔犲拰浣跨敤銆?br /> 濡傛灉瑙夊緱 C++ 鍙樺寲澶ぇ浜嗭紝涓嶅繀鎯婃亹錛岃姳鐐規(guī)椂闂存潵瀛︿範灝卞ソ浜嗐傚彲鑳藉湪浣犺瀺浼氳瘡閫氭柊鐗規(guī)т互鍚庯紝浣犱細鍚屾剰 Stroustrup 鐨勮鐐癸細C++11 鏄竴闂ㄦ柊鐨勮璦——涓涓洿濂界殑 C++銆?p>
]]>
璁稿鏂頒漢瀵逛簬緙栬瘧B(tài)OOST鎰熷埌鏃犱粠涓嬫墜錛岀敋鑷沖洜姝よ屾斁寮冧嬌鐢˙OOST錛岄偅鐪熺殑澶彲鎯滀簡錛屼笅闈㈡垜鎶婁竴浜涘父鐢ㄧ殑BOOST緙栬瘧鏂規(guī)硶璐翠簬姝わ紝鍚屾椂涔熶綔涓鴻嚜宸辯殑絎旇銆?
棣栧厛涓嬭澆bjam.exe錛屽鍒跺埌 $BOOST$ 鐩綍涓嬨傛垨鑰?span style="FONT-SIZE: 14pt">鑷繁鐢熸垚bjam錛屾墦寮Visual Studio 2008 鍛戒護鎻愮ず紿楀彛$BOOST$\tools\jam\src錛屾墽琛?build.bat 浼氬湪$BOOST$\tools\jam\src\bin.ntx86 鐢熸垚 bjam.exe 鏂囦歡銆傚鍒舵枃浠?bjam.exe 鏂囦歡鍒?$BOOST$\涓?/span>銆?
1.瀹屽叏緙栬瘧瀹夎錛?
bjam --toolset=msvc install
瀹屾垚鍚庝細鐢熸垚涓涓猙in.v2緙栬瘧鏃剁殑涓存椂鐩綍錛屾墜鍔ㄥ垹闄ゃ傜敓鎴愬彟涓涓洰褰旵:\boost錛岄噷闈負鎵鏈夌殑澶存枃浠跺拰搴撴枃浠躲傚ご鏂囦歡鐩綍涓篵oost_1_34_1\boost鐩綍澶嶅埗榪囧幓鐨勩?br>
2.鍙紪璇戠浉搴旂殑搴撴枃浠?
bjam --toolset=msvc stage
瀹屾垚鍚庡悓鏍蜂細鐢熸垚bin.v2涓存椂鐩綍銆傚彟涓涓洰褰曚負stage鏂囦歡錛岄噷闈㈡湁瀵瑰簲鐨勫簱鏂囦歡銆?
3.鏌ョ湅闇瑕佺紪璇戞墠鑳戒嬌鐢ㄧ殑搴撳垪琛?
bjam --show-libraries
4.緙栬瘧鐗瑰畾鐨勫簱錛屽鍙紪璇憆egex
bjam --toolset=msvc --with-regex stage
鐢熸垚鐨勫簱鏂囦歡鍦╯tage鐩綍涓?
5.涓嶇紪璇戞煇涓簱錛屽涓嶇紪璇憆egex
bjam --toolset=msvc --without-regex stage
鐢熸垚鐨勫簱鏂囦歡鍦╯tage鐩綍涓?
6.緙栬瘧鐗瑰畾鐨勫簱錛屽鍙紪璇憆egex錛岀敓鎴恉ebug錛屽綰跨▼錛屽叡浜繛鎺ョ増鏈紝騫朵繚瀛樺湪stage銆?
bjam --toolset=msvc --with-regex stage debug threading=multi link=shared
7.鐢熸垚 mt-sgd 鐨勯潤鎬佸簱(runtime-link-static)
bjam "-sTOOLS=vc-8_0" --with-thread install debug release runtime-link=static
8.緙栬瘧regex搴撱?
bjam --toolset=msvc --with-regex stage debug release threading=multi threading=single link=shared link=static runtime-link=shared runtime-link=static
boost鐨勫畨瑁呮柟娉曪細
瀵逛簬DLL鐗堟湰
bjam --toolset=msvc link=shared runtime-link=shared threading=multi stage debug release install
瀵逛簬lib鐗堟湰
bjam --toolset=msvc link=static runtime-link=shared threading=multi stage debug release install
鍙﹀錛屽湪$BOOST$\tools\build\v2\user-config.jam鎵懼埌涓嬮潰鐨勫湴鏂?
# -------------------
# MSVC configuration.
# -------------------
# Configure msvc (default version, searched for in standard locations and PATH).
# using msvc ;
# Configure specific msvc version (searched for in standard locations and PATH).
# using msvc : 8.0 ;
#鍦ㄨ繖閲屾坊鍔?vs2008 鐨勯厤緗?
using msvc : 9.0 : : /wd4819 /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_SECURE_SCL=0 ;
#鍦ㄨ繖閲屾坊鍔?vs2005 鐨勯厤緗?
using msvc : 8.0 : : <compileflags>/wd4819 <compileflags>/D_CRT_SECURE_NO_DEPRECATE <compileflags>/D_SCL_SECURE_NO_DEPRECATE <compileflags>/D_SECURE_SCL=0 ;
鐒跺悗榪涘叆 $BOOST$ 鐩綍錛屾墽琛宐jam.exe 緙栬瘧鍛戒護
//涓嬮潰鐨勫懡浠ょ殑鍚勯夐」鐨勮鏄庯細
//prefix 灝哹oost瀹夎鍒扮殑璺緞錛堢敓鎴愮殑澶存枃浠跺拰搴撴枃浠墮兘浼氭斁鍒拌璺緞涓級銆?
//閲嶅畾涔変互涓嬪彉閲忥紙鍒╃敤-s璁劇疆錛夛細
//VC80_ROOT銆銆 vc2005鐨勫畨瑁呰礬寰勶紝濡傛灉鏈皢vc2005瀹夎鍒伴粯璁や綅緗紝浣犲繀欏繪寚瀹氳欏廣?
//TOOLS 浣跨敤鐨勭紪璇戝伐鍏鳳紝vc2005瀵瑰簲鐨勬槸vc-8_0
//PYTHON_ROOT ython鐨勫畨瑁呯洰褰曪紝濡傛灉鏈皢BOOST瀹夎鍒伴粯璁や綅緗紝浣犲繀欏繪寚瀹氳欏廣?
//BUILD 緙栬瘧緇撴灉閫夐」錛岄粯璁や細鐢熸垚灝藉彲鑳藉鐨勭増鏈紝濡傝皟璇曠増錛忓彂琛岀増錛岄潤鎬佸簱錛忓姩鎬佸簱錛屽崟綰跨▼錛忓綰跨▼銆?
]]>
浣滆咃細瀛熷博
--------------------------------------------------------------------------------------
榪欐槸閭g瘒C++0X鐨勬鏂囥傚お闀匡紝鍏堝啓涓婂崐閮ㄥ垎鍙戜簡銆?/p>
瀵硅薄鑼冨紡鍒欏弽鏄犱簡鍔沖姩鍒嗗伐涔嬪悗鐨勫洟闃熷崗浣滅殑宸ヤ綔鐗圭偣鈥斺旀瘡涓漢鍚勬湁鎵闀匡紝鍚勫徃鍏惰亴錛屾湁鍚勮嚜鐨勭鏈夎祫婧愶紝宸ヤ歡鍜屼俊鎭湪浜轟滑涔嬮棿褰兼浼犻掞紝鏈鍚庡畬鎴愬伐浣溿傚洜姝わ紝瀵硅薄鑼冨紡涔熷氨褰㈡垚浜嗚嚜宸卞紼嬪簭鐨勭湅娉曗斺旂▼搴忔槸鐢變竴緇勫璞$粍鎴愶紝榪欎簺瀵硅薄鍚勬湁鎵鑳斤紝閫氳繃娑堟伅浼犻掑疄鐜板崗浣溿?
瀵硅薄涔嬮棿浜掔浉鍙戦佹秷鎭紝鍗忎綔瀹屾垚浠誨姟錛?
{
private:
int *const ptr;
public:
A():ptr(NULL)
{
}
};
A one;
A two;
two = one;
鍞夛紝褰撴椂鐭ラ亾鏄繖涓師鍥犲悗鐪熺殑鏄緸娑╅毦褰擄紝鑷繁鏄庣煡閬揷onst涓嶈兘琚祴鍊兼槸甯歌瘑闂錛屼絾褰撴椂鍗存媧繪病鑳芥壘鍑哄師鍥犮?br>鑰屾洿瑕佷漢鍛界殑鏄垜涔嬪墠鍦?a href="http://m.shnenglu.com/zhaoyg/archive/2009/10/07/98041.html">{鍋跺皵瀛︿範C++鏍囧噯} 涔?[瀵硅薄鐨勫鍒?- 澶嶅埗鏋勯犱笌璧嬪兼搷浣滅] 涓氨宸茬粡瀵硅祴鍊兼搷浣滅鍋氫簡涓浜涚瑪璁幫紝浣嗘垜绔熺劧鎶婁竴浜涘唴瀹圭粰蹇樹簡錛堜篃鍙兘鏄帇鏍瑰氨娌℃敞鎰忥級銆?br>
鐜板湪閲嶆柊灝辮嚜鍔ㄥ悎鎴愮殑璧嬪兼搷浣滅浣曟椂涓嶈兘浣跨敤鍐嶅崟鐙仛涓嬈$瑪璁般?br>
褰撶被涓嫢鏈変互涓嬩竴縐嶆垨鍑犵鎯呭喌鏃訛紝闅愬紡瀹氫箟鐨勮祴鍊兼搷浣滅鏄笉鑳戒嬌鐢ㄧ殑錛?br>1.闈為潤鎬佺殑const鎴愬憳鍙橀噺
2.闈為潤鎬佺殑寮曠敤綾誨瀷鎴愬憳鍙橀噺
3.闈為潤鎬佺殑綾葷被鍨嬬殑鎴愬憳鍙橀噺鐨勮祴鍊兼搷浣滅涓嶅彲璁塊棶
4.錛堝鏋滄湁錛夊熀綾諱腑鐨勮祴鍊兼搷浣滅涓嶅彲璁塊棶
娉紝瀵逛簬鎷ユ湁浠ヤ笂鎯呭喌涓殑涓縐嶆垨澶氱鐨勭被錛屾爣鍑嗕腑鐨勭敤璇嶆槸錛歩ll-formed銆傛垜涓嶇煡閬撲負浠涔堣鐢╥ll-formed錛堝瓧闈㈡剰鎬濓細涓嶈鑼冿級錛屼絾涓嶇鎬庢牱錛屽浜巌ll-formed錛岀紪璇戝櫒鐨勮涓哄氨鏄紝鏃犳硶緙栬瘧閫氳繃銆?br>
鍚庤錛氬笇鏈涜繖嬈′笉瑕佸啀蹇樿榪欎簺鍐呭浜嗐?
]]>
濡傚浘錛?br>
*/ };
褰撴垜鐪嬪埌涓婇潰榪欐牱鐨勪唬鐮佹椂錛屾垜渚胯涓鴻繖涓唬鐮佹棤娉曠紪璇戦氳繃鐨勶紝鍥犱負鎸夋垜鎵鐭ラ亾鐨勶紝鍑芥暟fun鎵榪斿洖鐨勬槸涓涓復鏃跺璞★紝鑰屼復鏃跺璞℃槸涓嶈兘琚慨鏀圭殑錛岀劧鑰宖un()=T()璇彞渚挎伆鎭版槸鍦ㄥ涓存椂瀵硅薄榪涜淇敼銆備絾鏄綋鎴戠紪璇戜箣鍚庡嵈鍌葷溂浜嗭紝灞呯劧閫氳繃浜嗭紝鎴戝緢綰抽椃銆?br>鍚庢潵鍦ㄧ綉鍙嬬殑甯姪涓嬶紝鍦ㄦ爣鍑嗕腑鎵懼埌浜嗙瓟妗堬細
3.10.5
The result of calling a function that does not return a reference is an rvalue. User defined operators are functions, and whether such operators expect or yield lvalues is determined by their parameter and return types.
13.5.7
The identities among certain predefined operators applied to basic types (for example, ++a ≡ a+=1) need not hold for operator functions. Some predefined operators, such as +=, require an operand to be an lvalue when applied to basic types; this is not required by operator functions.
3.10
An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can also be used to modify its referent under certain circumstances. [Example: a member function called for an object (9.3) can modify the object. ]
涔熷氨鏄錛屽湪瀵瑰唴緗被鍨嬭繘琛岃祴鍊兼搷浣滄椂錛屽皢璋冪敤鍐呯疆鐨勮祴鍊兼搷浣滅錛岃岃繖縐嶅唴緗殑瑕佹眰宸︽搷浣滄暟蹇呴』鏄乏鍊鹼紱鑰屽綋瀵圭被綾誨瀷瀵硅薄榪涜璧嬪兼椂錛屾墍璋冪敤鐨勬槸閲嶈澆鐨勮祴鍊兼搷浣滅錛屼絾閲嶈澆鐨勬搷浣滅騫舵病鏈夎姹傚繀欏諱嬌鐢ㄥ乏鍊鹼紝涔熷氨鏄錛岃祴鍊兼搷浣滅鐨勫乏鎿嶄綔鏁板彲浠ユ槸鍙沖箋?br>鍚庢潵寰楃煡錛屽湪C++涓彸鍊煎彲浠ユ槸涓涓璞★紝鑰?#8220;瀵硅薄”灝辨寚鐨勬槸“涓孌靛唴瀛樺瓨璐尯鍩?#8221;錛屼絾C涓殑鍙沖煎垯涓嶆槸涓涓璞★紝浠栧彧鏄竴涓箋?br>
浠ヤ笂鍐呭濡傛湁涓嶅涔嬪錛岃繕鏈涗笉鎯滄寚姝c?br>
瀵筶value鍜宺value鐨勮緝璇︾粏浠嬬粛璇風湅鏂囩珷<Lvalues and Rvalues>錛?a href="http://m.shnenglu.com/zhaoyg/archive/2010/02/06/107405.html">http://m.shnenglu.com/zhaoyg/archive/2010/02/06/107405.html
Most books on C or C++ do not explain lvalues and rvalues very well. (I looked in a dozen books and couldn't find one explanation I liked.) This may be due to of the lack of a consistent definition even among the language standards. The 1999 C Standard defines lvalue differently from the 1989 C Standard, and each of those definitions is different from the one in the C++ Standard. And none of the standards is clear.
Given the disparity in the definitions for lvalue and rvalue among the language standards, I'm not prepared to offer precise definitions. However, I can explain the underlying concepts common to the standards.
As is often the case with discussions of esoteric language concepts, it's reasonable for you to ask why you should care. Admittedly, if you program only in C, you can get by without understanding what lvalues and rvalues really are. Many programmers do. But understanding lvalues and rvalues provides valuable insights into the behavior of built-in operators and the code compilers generate to execute those operators. If you program in C++, understanding the built-in operators is essential background for writing well-behaved overloaded operators.
Basic concepts
--------------------------------------------------------------------------------
Kernighan and Ritchie coined the term lvalue to distinguish certain expressions from others. In The C Programming Language (Prentice-Hall, 1988), they wrote "An object is a manipulatable region of storage; an lvalue is an expression referring to an object....The name 'lvalue' comes from the assignment expression E1 = E2 in which the left operand E1 must be an lvalue expression."
In other words, the left and right operands of an assignment expression are themselves expressions. For the assignment to be valid, the left operand must refer to an object-it must be an lvalue. The right operand can be any expression. It need not be an lvalue. For example:
int n;
declares n as an object of type int. When you use n in an assignment expression such as:
n = 3;
n is an expression (a subexpression of the assignment expression) referring to an int object. The expression n is an lvalue.
Suppose you switch the left and right operands around:
3 = n;
Unless you're a former Fortran programmer, this is obviously a silly thing to do. The assignment is trying to change the value of an integer constant. Fortunately, C and C++ compilers reject it as an error. The basis for the rejection is that, although the assignment's left operand 3 is an expression, it's not an lvalue. It's an rvalue. It doesn't refer to an object; it just represents a value.
I don't know where the term rvalue comes from. Neither edition of the C Standard uses it, other than in a footnote stating "What is sometimes called 'rvalue' is in this standard described as the 'value of an expression.'"
The C++ Standard does use the term rvalue, defining it indirectly with this sentence: "Every expression is either an lvalue or an rvalue." So an rvalue is any expression that is not an lvalue.
Numeric literals, such as 3 and 3.14159, are rvalues. So are character literals, such as 'a'. An identifier that refers to an object is an lvalue, but an identifier that names an enumeration constant is an rvalue. For example:
enum color { red, green, blue };
color c;
...
c = green; // ok
blue = green; // error
The second assignment is an error because blue is an rvalue.
Although you can't use an rvalue as an lvalue, you can use an lvalue as an rvalue. For example, given:
int m, n;
you can assign the value in n to the object designated by m using:
m = n;
This assignment uses the lvalue expression n as an rvalue. Strictly speaking, a compiler performs what the C++ Standard calls an lvalue-to-rvalue conversion to obtain the value stored in the object to which n refers.
Lvalues in other expressions
-------------------------------------------------------------------------------
Although lvalues and rvalues got their names from their roles in assignment expressions, the concepts apply in all expressions, even those involving other built-in operators.
For example, both operands of the built-in binary operator + must be expressions. Obviously, those expressions must have suitable types. After conversions, both expressions must have the same arithmetic type, or one expression must have a pointer type and the other must have an integer type. But either operand can be either an lvalue or an rvalue. Thus, both x + 2 and 2 + x are valid expressions.
Although the operands of a binary + operator may be lvalues, the result is always an rvalue. For example, given integer objects m and n:
m + 1 = n;
is an error. The + operator has higher precedence than the = operator. Thus, the assignment expression is equivalent to:
(m + 1) = n; // error
which is an error because m + 1 is an rvalue.
As another example, the unary & (address-of) operator requires an lvalue as its operand. That is, &n is a valid expression only if n is an lvalue. Thus, an expression such as &3 is an error. Again, 3 does not refer to an object, so it's not addressable.
Although the unary & requires an lvalue as its operand, it's result is an rvalue. For example:
int n, *p;
...
p = &n; // ok
&n = p; // error: &n is an rvalue
In contrast to unary &, unary * produces an lvalue as its result. A non-null pointer p always points to an object, so *p is an lvalue. For example:
int a[N];
int *p = a;
...
*p = 3; // ok
Although the result is an lvalue, the operand can be an rvalue, as in:
*(p + 1) = 4; // ok
Data storage for rvalues
--------------------------------------------------------------------------------
Conceptually, an rvalue is just a value; it doesn't refer to an object. In practice, it's not that an rvalue can't refer to an object. It's just that an rvalue doesn't necessarily refer to an object. Therefore, both C and C++ insist that you program as if rvalues don't refer to objects.
The assumption that rvalues do not refer to objects gives C and C++ compilers considerable freedom in generating code for rvalue expressions. Consider an assignment such as:
n = 1;
where n is an int. A compiler might generate named data storage initialized with the value 1, as if 1 were an lvalue. It would then generate code to copy from that initialized storage to the storage allocated for n. In assembly language, this might look like:
one: .word 1
...
mov (one), n
Many machines provide instructions with immediate operand addressing, in which the source operand can be part of the instruction rather than separate data. In assembly, this might look like:
mov #1, n
In this case, the rvalue 1 never appears as an object in the data space. Rather, it appears as part of an instruction in the code space.
On some machines, the fastest way to put the value 1 into an object is to clear it and then increment it, as in:
clr n
inc n
Clearing the object sets it to zero. Incrementing adds one. Yet data representing the values 0 and 1 appear nowhere in the object code.
More to come
--------------------------------------------------------------------------------
Although it's true that rvalues in C do not refer to objects, it's not so in C++. In C++, rvalues of a class type do refer to objects, but they still aren't lvalues. Thus, everything I've said thus far about rvalues is true as long as we're not dealing with rvalues of a class type.
Although lvalues do designate objects, not all lvalues can appear as the left operand of an assignment. I'll pick up with this in my next column.
濡備笅錛?/p>
--------------------------------------------------------------------------------
Non-modifiable Lvalues
--------------------------------------------------------------------------------
Lvalues actually come in a variety of flavors. If you really want to understand how compilers evaluate expressions, you'd better develop a taste.
const 闄愬畾絎︾殑鍚箟錛?姣斿 int const m;
瀹冨茍涓嶆槸璇磎鐨勫間笉鑳借淇敼, 鑰屾槸鎸?m 涓嶈兘淇敼瀹冨紩鐢ㄧ殑瀵硅薄錛?br>e.g:
int m;
int const *p = &m;
m += 1; //right
*p += 1; //wrong
An expression is a sequence of operators and operands that specifies a computation. That computation might produce a resulting value and it might generate side effects. An assignment expression has the form:
e1 = e2
where e1 and e2 are themselves expressions. The right operand e2 can be any expression, but the left operand e1 must be an lvalue expression. That is, it must be an expression that refers to an object. As I explained last month ("Lvalues and Rvalues," June 2001, p. 70), the "l" in lvalue stands for "left," as in "the left side of an assignment expression." For example:
int n;
declares n as an object of type int. When you use n in an assignment expression such as:
n = 3;
the n is an expression (a subexpression of the assignment expression) referring to an int object. The expression n is an lvalue. On the other hand:
3 = n;
causes a compilation error, and well it should, because it's trying to change the value of an integer constant. Although the assignment's left operand 3 is an expression, it's not an lvalue. It's an rvalue. An rvalue is simply any expression that is not an lvalue. It doesn't refer to an object; it just represents a value.
Although lvalue gets its name from the kind of expression that must appear to the left of an assignment operator, that's not really how Kernighan and Ritchie defined it. In the first edition of The C Programming Language (Prentice-Hall, 1978), they defined an lvalue as "an expression referring to an object." At that time, the set of expressions referring to objects was exactly the same as the set of expressions eligible to appear to the left of an assignment operator. But that was before the const qualifier became part of C and C++.
The const qualifier renders the basic notion of lvalues inadequate to describe the semantics of expressions. We need to be able to distinguish between different kinds of lvalues. And that's what I'm about to show you how to do. But first, let me recap.
A few key points
--------------------------------------------------------------------------------
The assignment operator is not the only operator that requires an lvalue as an operand. The unary & (address-of) operator requires an lvalue as its sole operand. That is, &n is a valid expression only if n is an lvalue. Thus, an expression such as &3 is an error. The literal 3 does not refer to an object, so it's not addressable.
Not only is every operand either an lvalue or an rvalue, but every operator yields either an lvalue or an rvalue as its result. For example, the binary + operator yields an rvalue. Given integer objects m and n:
m + 1 = n;
is an error. The + operator has higher precedence than the = operator. Thus, the assignment expression is equivalent to:
(m + 1) = n; // error
which is an error because m + 1 is an rvalue.
An operator may require an lvalue operand, yet yield an rvalue result. The unary & is one such operator. For example:
int n, *p;
...
p = &n; // ok
&n = p; // error: &n is an rvalue
On the other hand, an operator may accept an rvalue operand, yet yield an lvalue result, as is the case with the unary * operator. A valid, non-null pointer p always points to an object, so *p is an lvalue. For example:
int a[N];
int *p = a;
...
*p = 3; // ok
Although the result is an lvalue, the operand can be an rvalue, as in:
*(p + 1) = 4; // ok
With this in mind, let's look at how the const qualifier complicates the notion of lvalues.
Lvalues and the const qualifier
--------------------------------------------------------------------------------
A const qualifier appearing in a declaration modifies the type in that declaration, or some portion thereof. For example: int const n = 127;
declares n as object of type "const int." The expression n refers to an object, almost as if const weren't there, except that n refers to an object the program can't modify. For example, an assignment such as:
n = 0; // error, can't modify n
produces a compile-time error, as does:
++n; // error, can't modify n
(I covered the const qualifier in depth in several of my earlier columns. See "Placing const in Declarations," June 1998, p. 19 or "const T vs. T const," February 1999, p. 13, among others.) How is an expression referring to a const object such as n any different from an rvalue? After all, if you rewrite each of the previous two expressions with an integer literal in place of n, as in:
7 = 0; // error, can't modify literal ++7; // error, can't modify literal
they're both still errors. You can't modify n any more than you can an rvalue, so why not just say n is an rvalue, too? The difference is that you can take the address of a const object, but you can't take the address of an integer literal. For example:
int const *p;
...
p = &n; // ok
p = &7; // error
Notice that p declared just above must be a "pointer to const int." If you omitted const from the pointer type, as in:
int *p;
then the assignment:
p = &n; // error, invalid conversion
would be an error. When you take the address of a const int object, you get a value of type "pointer to const int," which you cannot convert to "pointer to int" unless you use a cast, as in:
p = (int *)&n; // (barely) ok
Although the cast makes the compiler stop complaining about the conversion, it's still a hazardous thing to do. (See "What const Really Means," August 1998, p. 11.)
Thus, an expression that refers to a const object is indeed an lvalue, not an rvalue. However, it's a special kind of lvalue called a non-modifiable lvalue-an lvalue that you can't use to modify the object to which it refers. This is in contrast to a modifiable lvalue, which you can use to modify the object to which it refers.
Once you factor in the const qualifier, it's no longer accurate to say that the left operand of an assignment must be an lvalue. Rather, it must be a non-modifiable lvalue. In fact, every arithmetic assignment operator, such as += and *=, requires a modifiable lvalue as its left operand. For all scalar types:
x += y; // arithmetic assignment
is equivalent to:
x = x + y; // assignment
except that it evaluates x only once. Since the x in this assignment must be a modifiable lvalue, it must also be a modifiable lvalue in the arithmetic assignment. Not every operator that requires an lvalue operand requires a modifiable lvalue. The unary & operator accepts either a modifiable or a non-modifiable lvalue as its operand. For example, given:
int m;
int const n = 10;
&m is a valid expression returning a result of type "pointer to int," and &n is a valid expression returning a result of type "pointer to const int."
What it is that's really non-modifiable
--------------------------------------------------------------------------------
Earlier, I said a non-modifiable lvalue is an lvalue that you can't use to modify an object. Notice that I did not say a non-modifiable lvalue refers to an object that you can't modify-I said you can't use the lvalue to modify the object. The distinction is subtle but nonetheless important, as shown in the following example. Consider:
int n = 0;
int const *p;
...
p = &n;
At this point, p points to n, so *p and n are two different expressions referring to the same object. However, *p and n have different types. As I explained in an earlier column ("What const Really Means"), this assignment uses a qualification conversion to convert a value of type "pointer to int" into a value of type "pointer to const int." Expression n has type "(non-const) int." It is a modifiable lvalue. Thus, you can use n to modify the object it designates, as in:
n += 2;
On the other hand, p has type "pointer to const int," so *p has type "const int." Expression *p is a non-modifiable lvalue. You cannot use *p to modify the object n, as in:
*p += 2;
even though you can use expression n to do it. Such are the semantics of const in C and C++.
In summary
--------------------------------------------------------------------------------
Every expression in C and C++ is either an lvalue or an rvalue. An lvalue is an expression that designates (refers to) an object. Every lvalue is, in turn, either modifiable or non-modifiable. An rvalue is any expression that isn't an lvalue. Operationally, the difference among these kinds of expressions is this:
Dan Saks is a high school track coach and the president of Saks & Associates, a C/C++ training and consulting company. You can write to him at dsaks@wittenberg.edu.
鏈枃鏉ヨ嚜CSDN鍗氬錛岃漿杞借鏍囨槑鍑哄錛?a >http://blog.csdn.net/SeeSeaBee/archive/2007/09/08/1777120.aspx
class Base1

{
public:
virtual void f()
{
cout << "Base1::f" << endl;
}
virtual void g()
{
cout << "Base1::g" << endl;
}
};
class Base2 :public virtual Base1

{
public:
virtual void f()
{
cout << "Base2::f" << endl;
}
virtual void g()
{
cout << "Base2::g" << endl;
}
};
class Base3:public virtual Base1

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

class Derive : public Base2, public Base3
{
public:
virtual void g()
{ cout << "Derive::g1" << endl; }
};浠ヤ笂浠g爜鏄湪璁哄潧涓亣瑙佺殑錛屽綋鏃舵垜騫舵病鏈夌珛鍒誨弽搴斾笂鏉ヨ繖鏄粈涔堢紭鏁咃紝鎬濈儲涓闃靛悗錛屾墠寮勬槑鐧姐?br>鍘熸潵錛屽湪Derive涓病鏈夐噸鍐檉鍑芥暟錛屽張鍥犱負褰撴淳鐢熺被娌℃湁閲嶅啓鍩虹被鐨勮櫄鍑芥暟鏃訛紝媧劇敓綾誨璞″璇ヨ櫄鍑芥暟鐨勮皟鐢紝灝嗕細璋冪敤鍏跺熀綾諱腑鐨勭増鏈紝鑰孌erive鍙堟槸澶氱戶鎵匡紝浜庢槸鍦―erive緇ф壙鏃跺氨涓嶇煡閬揃ase1涓殑铏氬嚱鏁拌〃搴旇璁板綍鍝釜鐗堟湰鐨刦鍑芥暟錛屾槸Base2錛岃繕鏄疊ase3銆?br>鍥犱負Derive涓凡閲嶅畾涔塯鍑芥暟錛孊ase1鐨勮櫄鍑芥暟琛ㄨ褰曠殑鏄疍erive::g銆?/p>
==============================================================================
闂2錛?br>浠g爜鏉ユ簮<effective C++>2nd
鏉ユ簮錛氬紭灝?nbsp; http://www.bansun.com/bbs/thread-4880-1-5.html