锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
鍦∕FC鐨勬秷鎭槧灝勮〃鐨勫緩绔嬩腑錛岄氳繃涓緇勫畯錛屼綘灝卞彲浠ヨ鑷繁鐨勭被鍏堜簬鐖剁被澶勭悊鏌愪簺Windows娑堟伅錛岃繖縐嶈涓哄緢鍍忚櫄鍑芥暟錛屽彧鏄垜浠噸杞界殑鍐呭涓嶆槸铏氬嚱鏁幫紝鑰屾槸娑堟伅銆?/font>
鎺ㄥ姩娑堟伅鐨勬車
榪欐牱錛岄氳繃AfxHookWindowCreate錛屽湪褰撳墠綰跨▼涓畨瑁呬簡涓涓挬瀛愶紝鐢ㄦ潵鎷︽埅鍜岀獥鍙g浉鍏崇殑浜嬩歡錛屾瘡褰擄細
榪欐牱錛宊AfxCbtFilterHook鐨勫伐浣滄葷粨璧鋒潵灝辨槸閫氳繃紿楀彛瀛愮被鍖栵紝鎶婃柊寤虹殑紿楀彛鐨勭獥鍙h繃紼嬭緗垚AfxWndProc銆?br />鍒拌繖閲岋紝鎴戜滑緇堜簬鎵懼埌浜嗙獥鍙h繃紼嬨?br />
]]>
鐢ㄦ渶鍩烘湰鐨勪竴鍙ヨ瘽姒傝堪錛岄挬瀛愬嚱鏁拌搗浜嗗緢澶т綔鐢ㄣ傛晠浜嬫槸榪欐牱鐨勶紝鏈変簺婕暱錛屼篃闇瑕佷簺鑰愬績銆?br />
MFC涓秷鎭垎涓?綾伙細
聽1. WM_COMMAND錛氭墍鏈夌殑UI緇勪歡鍜屽姞閫熼敭閮戒細浜х敓榪欑娑堟伅錛屾墍鏈夋淳鐢熶簬CCmdTarget鐨勭被閮芥湁鑳藉姏澶勭悊璇ユ秷鎭?br />聽2. 鏍囧噯娑堟伅錛氶櫎WM_COMMAND涔嬪鐨刉M_xx娑堟伅閮芥槸鏍囧噯娑堟伅錛屾淳鐢熶簬CWnd鐨勭被閮芥湁鑳藉姏澶勭悊璇ユ秷鎭?br />聽3. 鎺т歡閫氱煡娑堟伅錛氱敤浜庡瓙紿楀彛鎺т歡鍚戠埗紿楀彛鍙戦佺殑娑堟伅
絎竴闃舵 紿楀彛榪囩▼
鍦ㄤ駭鐢熶竴涓獥鍙g殑鏃跺欙紝浼氳皟鐢–FrameWnd::Create錛屾墍鏈夌殑鏁呬簨涔熼兘浠庤繖閲屽睍寮銆備笅闈㈢殑浠g爜涓轟簡綆媧侊紝鍘繪帀浜嗕笉鐩稿叧鐨勪唬鐮?br />
BOOL聽CFrameWnd::Create(鈥?聽
{
聽聽聽聽
//
聽鈥?/span>
聽聽聽聽
if
聽(
!
CreateEx(鈥?)聽
{
聽聽聽聽聽聽聽聽
//
聽鈥?/span>
聽聽聽聽}
聽聽聽聽
//
聽鈥?/span>
}
BOOL聽CWnd::CreateEx(鈥?聽
{
聽聽聽聽
//
聽鈥?/span>
聽聽聽聽AfxHookWindowCreate(
this
);
聽聽聽聽HWND聽hWnd聽
=
聽::CreateWindowEx(鈥?;
聽聽聽聽
//
聽鈥?/span>
}
void
聽AFXAPI聽AfxHookWindowCreate(CWnd
*
聽pWnd)聽
{
聽聽聽聽
//
聽鈥?/span>
聽聽聽聽
if
聽(pThreadState
->
m_hHookOldCbtFilter聽
==
聽NULL)聽
{
聽聽聽聽聽聽聽聽pThreadState
->
m_hHookOldCbtFilter聽
=
聽::SetWindowsHookEx(WH_CBT,
聽聽聽聽聽聽聽聽_AfxCbtFilterHook,聽NULL,聽::GetCurrentThreadId());
聽聽聽聽聽聽聽聽
//
聽鈥?/span>
聽聽聽聽}
聽聽聽聽
//
聽鈥?/span>
聽聽聽聽pThreadState
->
m_pWndInit聽
=
聽pWnd;
}
1. 鍙︿竴涓獥鍙f垚涓篴ctive錛?br />2. 浜х敓鎴栨懅姣佷竴涓獥鍙?br />3. Minimize鎴杕aximize涓涓獥鍙o紱
4. 縐誨姩鎴栫緝鏀句竴涓獥鍙o紱
5. 瀹屾垚涓涓潵鑷郴緇熻彍鍗曠殑鍛戒護錛?br />6. 浠庣郴緇熼槦鍒椾腑鍙栧嚭涓涓秷鎭紱
鏃訛紝閮戒細鍏堣皟鐢╛AfxCbtFilterHook錛屾帴涓嬫潵鐪嬬湅閽╁瓙鍑芥暟浣滀簡浠涔堬細
LRESULT聽CALLBACK
_AfxCbtFilterHook(
int
聽code,聽WPARAM聽wParam,聽LPARAM聽lParam)聽
{
聽聽聽聽
//
聽鈥?/span>
聽聽聽聽WNDPROC聽afxWndProc聽
=
聽AfxGetAfxWndProc();
聽聽聽聽oldWndProc聽
=
聽(WNDPROC)SetWindowLongPtr(hWnd,聽GWLP_WNDPROC,(DWORD_PTR)afxWndProc);
聽聽聽聽
//
聽鈥?/span>
}
WNDPROC聽AFXAPI聽AfxGetAfxWndProc()聽
{
聽聽聽聽
//
聽鈥?/span>
聽聽聽聽
return
聽
&
AfxWndProc;
}
緇撹
CFrameWnd::Create鍒涘緩紿楀彛璋冪敤CWnd::CreateEx
CWnd::CreateEx璋冪敤AfxHookWindowCreate鍑嗗涓虹獥鍙h緗挬瀛?br />AfxHookWindowCreate璋冪敤::SetWindowHookEx涓虹獥鍙h緗簡涓涓猈H_CBT綾誨瀷鐨勯挬瀛愭潵榪囨護娑堟伅錛屽茍鎶婅繃婊ゅ嚱鏁拌緗垚_AfxCbtFilterHook
_AfxCbtFilterHook閫氳繃紿楀彛瀛愮被鍖栬緗獥鍙g殑紿楀彛榪囩▼涓篈fxWndProc
榪欐牱錛岄氳繃::DispatchMessage鍙戦佺粰紿楀彛鐨勬秷鎭氨浼氭簮婧愪笉鏂湴閫佸埌AfxWndProc涓潵錛屽彲浠ユ兂鍒幫紝AfxWndProc鍒╃敤MFC鐨勬秷鎭槧灝勮〃錛屽垎闂ㄥ埆綾葷殑瀵規秷鎭繘琛屽垎嫻併?br />
錛堝緟緇︹︼級
]]>
鍏朵腑銆typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void);
涔嬪悗錛岄氳繃涓涓摼琛紝鎶婅繖浜涙弿榪版秷鎭殑緇撴瀯緇勭粐璧鋒潵錛屾瀯鎴愭秷鎭槧灝勮〃鐨勭粨鏋勬槸AFX_MSGMAP
榪欐牱涓涓狝FX_MSGMAP瀵硅薄灝辨垚浜嗘瀯寤烘秷鎭槧灝勮〃鐨勫叧閿漢鐗╋紝瀹冧竴鍙墜鎷夌潃鍩虹被鐨凙FX_MSGMAP瀵硅薄錛屽彟涓鍙墜鎷夌潃綾繪湰韜殑娑堟伅鏄犲皠琛紝榪欐牱鍙姝g‘鍦板湪姣忎竴涓被涓兘瀹夋彃涓涓狝FX_MSGMAP瀵硅薄錛岄偅涔堟暣涓秷鎭槧灝勮〃灝卞緩绔嬭搗鏉ヤ簡銆傞偅涔堬紝浣曚負姝g‘鍛紵鍚箟鏈?錛氫竴鏄紜殑璁劇疆pBaseMap錛屼護瀹冩寚鍚戝熀綾伙紝浜屾槸姝g‘鐨勫緩绔嬬被鑷韓鐨勬秷鎭槧灝勮〃銆傝繖涓や釜宸ヤ綔鏄敱4涓畯瀹屾垚鐨勶紝
瀹冧滑鏄細DECLARE_MEMSSAGE_MAP() / BEGIN_MESSAGE_MAP() / ON_COMMAND()錛堟敞錛歄N_COMMAND瀹忓彧鏄負浜嗗鐞嗗懡浠ゆ秷鎭紝瀵逛簬鍏跺畠鐨勬秷鎭繕鏈夊搴旂殑瀹忥紝浣嗘槸鍘熺悊鏄浉鍚岀殑錛?/ END_MESSAGE_MAP()銆?br />璁╂垜浠竴涓釜鐨勭湅鐪嬶細
榪欎釜瀹忕殑浣滅敤鏈?錛?br />聽1. 鍦ㄧ被涓彃鍏ヤ竴涓潤鎬佹垚鍛榑messageEntries錛岃繖鏄敤鏉ュ瓨鏀劇被瑕佸鐞嗙殑娑堟伅鐨勬暟緇勶紙鍗崇被鏈韓鐨勬秷鎭槧灝勮〃錛?br />聽2.聽 鍙︿竴涓潤鎬佹垚鍛榤assageMap鐢ㄦ潵鎸囧悜鍩虹被鐨勬秷鎭槧灝勮〃
聽3. 瀹夋彃涓涓櫄鍑芥暟錛屽叾鍐呭鏈夊緟瀹炵幇
鎺ヤ笅鏉ワ紝_messageEntries鐨勫垵濮嬪寲錛宮essageMap鐨勬紜寚鍚戯紝GetMessageMap鍑芥暟鐨勫疄鐜拌繖浜涘伐浣滆繕閮芥病鍋氾紝閭f鏄悗涓変釜瀹忕殑璐d換錛屽畠浠欏哄簭浣跨敤錛屾柟鑳藉伐浣滄甯搞?
榪欎釜瀹忕殑浣滅敤鏈?錛?br />1. 瀹氫箟浜嗗畨鎻掑湪綾諱腑鐨勮櫄鍑芥暟GetMessageMap()錛屽彧鏄畝鍗曠殑榪斿洖messageMap瀵硅薄鐨勫湴鍧
2. 鍒濆鍖杕essageMap錛屾妸媧劇敓綾誨拰鍩虹被鑱旂郴璧鋒潵鏋勬垚涓涓ぇ鐨勬秷鎭槧灝勮〃
3. 涓虹被鏈韓鐨勬秷鎭槧灝勮〃鐨勫垵濮嬪寲鍋氳娉曞噯澶?/font>
ON_COMMAND榪欎釜瀹忕殑浣滅敤灝辨槸鍚慱messageEntries鏁扮粍涓坊鍔犵被鏈韓瑕佸鐞嗙殑鍛戒護娑堟伅錛屽叾瀹炲湪MFC涓繕鏈夊緢澶氭洿鏂逛究鐨勫畯鍙互鍚戠被涓坊鍔犳秷鎭紝渚嬪OM_WM_PAINT絳夛紝榪欓噷錛屾垜浠富瑕佽璁篛N_COMMAND錛屾瘯绔熷師鐞嗛兘鏄浉鍚岀殑銆?br />
鏃犻潪鏄AFX_MSG_ENTRY緇撴瀯鐨勫垵濮嬪寲錛岃繖鏍峰湪綾諱腑涓烘瘡涓涓兂瑕佸鐞嗙殑娑堟伅閮芥槸鐢ㄤ竴涓狾N_COMMAND瀹忥紝灝辮嚜鍔ㄧ殑鍒濆鍖栦簡綾繪湰韜殑娑堟伅鏄犲皠琛ㄣ?/font>
鏈鍚庯紝褰撳叏閮ㄧ殑淇℃伅娣誨姞瀹屾瘯鍚庯紝浣跨敤END_MESSAGE_MAP()瀹忛氱煡MFC涓涓被娑堟伅鏄犲皠琛ㄧ粨鏉熶簡銆?br />
瀹炵幇鎵嬫硶鍗曠函寰楀緢錛屾棤闈炴槸涓涓叏0鐨凙FX_MESSAGE_MAP瀵硅薄銆?br />
緇撹
鎯寵璁╀綘鐨勭被澶勭悊鏌愪釜娑堟伅錛屼嬌鐢ㄤ笅闈㈢殑緇勫悎錛?/font>
鍦∕FC涓紝瀵硅薄鐨勫姩鎬佸垱寤鴻渚濊禆浜嶳TTI鎵寤虹珛璧鋒潵鐨勭被鍒瀷褰曪紝鍜屽姩鎬佸垱寤烘湁鍏崇殑CRuntimeClass鎴愬憳鏈変袱涓細
鍒╃敤RTTI寤虹珛鐨勭被鍒瀷褰曪紝DECLARE_DYNCREATE / IMPLEMENT_DYNCREATE緇х畫涓虹被娣誨姞浜嗗姩鎬佸垱寤虹殑鍔熻兘銆?/p>
榪欎釜瀹忓悓鏍風敤鍦ㄧ被澹版槑涓紝瀹冧笉浣嗕負綾繪坊鍔犱簡class##class_name瀵硅薄鍜孏etRuntimeClass()錛岃繕涓虹被鍔犲叆浜嗕竴涓潤鎬佸嚱鏁癈reateObject,鐢ㄦ潵榪涜瀵硅薄鐨勫姩鎬佸垱寤恒傚悓鏍稩MPLEMENT_DYNCREATE鐢ㄦ潵瀵逛笂闈㈡坊鍔犵殑鍐呭浣滃畾涔夊拰鍒濆鍖栧伐浣溿?/p>
鍜孖MPLEMENT_DYNAMIC涓嶅悓鐨勬槸錛岃繖閲岀殑IMPLEMENT_RUNTIMECLASS涓殑絎?涓弬鏁板茍涓嶄負NULL錛岃屾槸class_name::CreateObject錛岃繖鏍峰氨鎸囧畾浜嗙敤浜庡垱寤哄璞$殑鍑芥暟錛岃嚦浜庡叾瀹冪殑鍐呭錛屼笌RTTI娌℃湁浠涔堜笉鍚屻?br />
浜庢槸錛屾暣涓璞$殑鍔ㄦ佸垱寤鴻繃紼嬪氨鍙樺緱闈炲父綆鍗曚簡錛屽彧瑕佹垜浠壘鍒版煇涓壒瀹氱被鐨凜RuntimeClass瀵硅薄錛屽埄鐢╟lass##class_name.CreateObject()灝卞彲浠ヤ簡銆?/p>
緇撹
鎯寵浣犵殑綾誨湪MFC涓敮鎸佸姩鎬佸垱寤猴紝
1.聽鍦ㄧ被澹版槑涓嬌鐢―ECLARE_DYNAMIC
2. 鍦ㄧ被瀹氫箟鏂囦歡涓嬌鐢↖MPLEMENT_DYNAMIC錛屾鏃?br />聽聽聽 class##class_name.m_pfnCreateObject = class_name::CreateObject;銆
聽聽聽 CRuntimeClass::CreateObject鍒╃敤m_pfnCreateObject灝卞彲浠ヨ繘琛屽璞$殑鍔ㄦ佸垱寤轟簡
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 錛堝緟緇︹︼級
鍙﹀錛孯UNTIME_CLASS灝辨槸鐢ㄦ潵鑾峰緱class##class_name瀵硅薄鍦板潃鐨勫畯錛?br />
榪欐牱錛屽綋瀵圭▼搴忎腑鐨勬瘡涓涓被閮戒嬌鐢ㄤ簡DECLARE_DYNAMIC / IMPLEMENT_DYNAMIC瀹忎箣鍚庯紝灝變負璇ョ被鍦ㄧ被鍒瀷褰曚腑榪涜浜嗙櫥璁板伐浣溿傚綋鐒訛紝MFC涓墍鏈夌殑綾婚兘媧劇敓浜嶤Object錛屾墍浠ユ墍鏈夌殑璺嚎鏈緇堥兘瑕佸湪CObject澶勪細鍚堬紝鐢變簬CObject娌℃湁鍩虹被錛屾墍浠ュ畠鐨凜RuntimeClass瀵硅薄騫朵笉鑳界敤涓婇潰鐨勪袱涓畯鏉ュ疄鐜幫紝鍦╫bjcore.cpp涓紝涓篊Object鐨刢lassCObject瀵硅薄鍗曠嫭浣滀簡鍒濆鍖栫殑宸ヤ綔錛?/p>
鎴戜滑鍙互鐪嬪埌m_pBaseClass琚垵濮嬪寲涓篘ULL銆傚彟澶栵紝涔熷崟鐙疄鐜頒簡GetRuntimeClass():
鑷充簬_RUNTIME_CLASS錛屽墠闈㈠凡緇忚榪囦簡銆傝繖鏍鳳紝濡傛灉鎯寵鎶婅嚜宸辯殑綾諱粙緇嶇粰MFC錛屽彧瑕佸湪綾誨0鏄庝腑浣跨敤DECLARE_DYNAMIC錛屽湪綾葷殑瀹炵幇涓姞鍏MPLEMENT_DYNAMIC
錛屽氨鍙互鎶婅嚜宸辨敞鍐屽埌綾誨埆鍨嬪綍涓簡銆傝嚦姝わ紝涓轟簡瀹炵幇綾誨璞$殑RTTI錛屾垜浠凡緇忓仛濂戒簡鎵鏈夌殑鍑嗗宸ヤ綔錛屼笅闈㈠氨鏉ョ湅涓涓嬪畠鐨勫疄鐜幫紝瀹冧富瑕佹槸闈燙Object涓殑IsKindOf鍑芥暟瀹屾垚鐨勩?/p>
榪欓噷錛岀敱浜嶨etRuntimeClass鏄櫄鍑芥暟錛屾墍浠ClassThis浼氭寚鍚戣皟鐢↖sKindOf鍑芥暟鐨勭被瀵硅薄鐨刢lass##class_name錛屼箣鍚庡埄鐢ㄦ寚鍚戣瀵硅薄鐨勬寚閽堣皟鐢↖sDerivedFrom錛?/p>
2涓換鎰忕被鍨?span lang="EN-US">U鍜?span lang="EN-US">T錛屽浣曠‘瀹?span lang="EN-US">T鑳藉惁鑷姩杞崲鎴?span lang="EN-US">U鍛紵
sizeof鐢ㄥ湪浠諱綍澶嶆潅鐨勮〃杈懼紡涓婏紝 sizeof鍙互榪斿洖榪欎釜琛ㄨ揪寮忓肩殑澶у皬錛岃屼笉浼氬湪榪愯鏃惰瘎浼拌〃杈懼紡鐨勫箋傝繖涔熷氨鎰忓懗鐫錛屼綘鍙互鎶婂嚱鏁伴噸杞姐佹ā鐗堝疄渚嬪寲銆佽漿鎹㈣鍒欑瓑絳夋墍鏈変綘鍙互鍦?span lang="EN-US">C++琛ㄨ揪寮忎腑浣跨敤鐨勮鏂界粺緇熷鍒?span lang="EN-US">sizeof涓潵銆傚疄闄呬笂錛?span lang="EN-US">sizeof闅愯棌浜嗕竴涓彲浠ユ紨緇庤〃杈懼紡綾誨瀷鐨勮鏂斤紝鏈緇堬紝sizeof浼氳繑鍥炶〃杈懼紡緇撴灉鐨勭被鍨嬨?span lang="EN-US">
sizeof鍜岄噸杞藉嚱鏁版潵瑙e喅鍒ゆ柇綾誨瀷涔嬮棿鐨勫彲杞崲鎬х殑闂銆傛濊礬寰堢畝鍗曪細鎴戜滑鎻愪緵2涓噸杞藉嚱鏁幫紝涓涓嚱鏁扮殑鍙傛暟鏄垜浠杞崲鎴愮殑綾誨瀷錛堟垜浠敤U琛ㄧず錛夛紝鑰屽彟涓涓垯鐢ㄦ潵鎺ユ敹鍏朵粬鎵鏈夌被鍨嬬殑鍙傛暟銆傜劧鍚庢垜浠妸瑕佹嫻嬬殑綾誨瀷錛堢敤T琛ㄧず錛変紶閫掔粰閲嶈澆鍑芥暟銆傚鏋滄帴鍙楃被鍨?span lang="EN-US">U涓哄弬鏁扮殑鍑芥暟琚皟鐢ㄤ簡錛屾垜浠氨璁や負T鍙互杞崲涓?span lang="EN-US">U錛屽弽涔嬪垯涓嶅彲浠ャ傚浣曠‘瀹氬摢涓嚱鏁拌璋冪敤浜嗗憿錛熸垜浠埄鐢?span lang="EN-US">sizeof鍑洪┈錛屾垜浠彧瑕佽閲嶈澆鍑芥暟榪斿洖涓嶅悓鐨勭被鍨嬶紝鐒跺悗媯鏌ヤ竴涓嬭繑鍥炲煎氨鍙互浜嗐?span lang="EN-US">
2涓笉鍚岀殑綾誨瀷錛?span lang="EN-US">
榛樿鎯呭喌涓嬶紝
sizeof(Small)
鏄?/span>
1
錛岃?/span>
Big
鐨勫ぇ灝忓垯鏃犲叧绱ц錛屾垜浠彧瑕佺煡閬撹偗瀹氫笉鏄?/span>
1
灝卞ソ浜嗐?/span>
鍏舵錛屽畾涔?/span>
2
涓噸杞藉嚱鏁幫紝涓涓帴鏀惰杞崲鎴愮殑綾誨瀷錛?/span>
Small Test(U);
鍙︿竴涓敤鏉ユ帴鏀垛滃叾浠栫殑鎵鏈夌被鍨嬧濓紝鎴戜滑瑕佷繚璇佸湪鎺掗櫎鎵鏈夌殑杞崲涔嬪悗鎵嶈皟鐢ㄨ繖涓嚱鏁幫紝
OK,
鐢ㄧ渷鐣ュ彿琛ㄧず鐨勫弬鏁板垪琛ㄧ湡濂芥弧瓚抽渶姹?/span>
Big Test(...);
灝界鎶婁竴涓?/span>
C++
瀵硅薄浼犻掔粰
...
鍙傛暟綾誨瀷鐨勫嚱鏁幫紝鍏剁粨鏋滄湭瀹氫箟錛屼絾鏄疄闄呬笂鎴戜滑騫舵病鏈夎皟鐢ㄨ繖涓嚱鏁般傛垜浠敋鑷沖彲浠ヤ笉鐢ㄥ疄鐜板畠銆?/span>
鏈鍚庯紝鎴戜滑鐢?/span>
sizeof
鍒ゆ柇涓涓嬪氨瀹屾垚浠誨姟浜嗭細
浣犱篃璁鎬細璇達紝灝辨槸瀹冧簡錛?/span>
Test
鐨勮皟鐢ㄤ細鍒涘緩涓涓復鏃跺璞?/span>
T
錛屼箣鍚庡彲鑳界殑緇撴灉鍙兘鏄?/span>
sizeof(Small)
鎴?/span>
sizeof(Big)
銆傚叴濂嬩箣浣欙紝鎴戜滑榪樿鐪嬪埌涓涓棶棰樸傚鏋?/span>
T
鐨勬瀯閫犲嚱鏁拌璁捐鎴?/span>
private
錛屾垜浠氨鍓嶅姛灝藉純浜嗐傚綋鐒惰В鍐崇殑鏂規硶涔熷緢綆鍗曪紝瀹氫箟涓涓嚱鏁幫紝璁╀粬榪斿洖綾誨瀷涓?/span>
T
鐨勫璞°?/span>
鏈鍚庯紝鎶婂垰鎵嶇殑涓滆タ灝佽鍒頒竴涓被閲岋細
鍙﹀錛屾垜浠繕鍙互璁劇疆鍙﹀涓涓父閲?/span>
Conversion::SameType
錛屽鏋?/span>
T
鍜?/span>
U
琛ㄧず鍚屼竴涓被鍨嬶紝閭d箞榪斿洖
true
錛?/span>
涔嬪悗涓哄悓涓涓被鍨嬭璁′竴涓亸鐗瑰寲鐗堟湰錛?/span>
鏈鍚庯紝鍥炲埌鎴戜滑鐨勪富棰橈紝閫氳繃
Conversion
鐨勫府鍔╋紝鎴戜滑鍙互鏉ュ喅瀹氫袱涓被鍨嬬殑緇ф壙鎬т簡銆?/span>
褰?/span>
U
緇ф壙浜?/span>
T
鎴栬?/span>
U
鍜?/span>
T
鏄悓涓涓被鍨嬬殑鏃跺欙紝
SUPERSUBCLASS
榪斿洖
true
銆傛葷粨涓涓嬶紝鍙湁涓嬮潰榪?/span>
3
縐嶆儏褰?/span>
const U*
鍙互闅愬紡杞崲鍒?/span>
const T*
錛?/span>
1.聽聽聽聽聽
T
鍜?/span>
U
鏄悓涓涓被鍨?/span>
2.聽聽聽聽聽
T
鏄?/span>
U
鐨勪換鎰忎竴涓熀綾?/span>
3.聽聽聽聽聽
T
鏄?/span>
void
鎴戜滑閫氳繃絎?/span>
2
涓祴璇曞睆钄戒簡鏈鍚庝竴縐嶆儏褰€傚綋鐒訛紝濡傛灉浣犺涓哄悓涓縐嶇被鍨嬩篃涓嶇畻鏄戶鎵垮叧緋葷殑璇濓紝鍙互榪涗竴姝ヤ弗鏍煎叾鏉′歡錛?/span>
Alexandrescu 鏈鍒濊璁$殑涓涓畝鍗曠殑妯$増錛岀幇鍦ㄦ垚浜嗘硾鍨嬭璁$殑甯哥敤鎵嬫硶錛?/span>
template
<int v>
struct
Int2Type {
聽聽聽
enum { value聽 = v };
};
瀵逛簬姣忎竴涓笉鍚岀殑甯告暣鏁幫紝
Int2Type
閮戒唬琛ㄤ笉鍚岀殑綾誨瀷銆傝繖鏄洜涓轟笉鍚岀殑妯$増瀹炰緥鍖栭兘浠h〃涓嶅悓鐨勭被鍨嬶紝涔熷氨鏄
Int2Type<0>
鍜?/span>
Int2Type<1>
鏄畬鍏ㄤ笉鍚岀殑銆?/span>
褰撲綘鎯蟲牴鎹紪璇戞椂緇撴灉鏉ヨ繘琛屾煇浜涙妷鎷┾斺斾緥濡傞夋嫨涓嶅悓鐨勫嚱鏁扳斺旀椂錛屼綘鍙互渚濊禆涓涓父鏁存暟鏉ュ府浣犲畬鎴愬垎媧懼伐浣滐紝榪欐椂
Int2Type
渚垮彲浠ュ府浣犳槸瀹炵幇榪欎釜鏂規硶銆?/span>
涓鑸潵璇達紝浣犲湪涓嬮潰涓や釜鎯呭喌涓渶瑕佷嬌鐢?/span>
Int2Type
錛?/span>
l
聽聽聽聽聽聽聽聽
浣犻渶瑕佹牴鎹紪璇戞椂甯擱噺鏉ヨ皟鐢ㄤ笉鍚岀殑鍑芥暟
l 聽聽聽聽聽聽聽聽 浣犻渶瑕佸湪緙栬瘧鏃舵墽琛屽垎媧懼伐浣?/span>
濡傛灉鏄湪榪愯鏃舵墽琛屽垎媧懼伐浣滐紝浣犲彲浠ョ敤
if-else
鎴?/span>
switch
璇彞鏉ョ畝鍗曠殑瀹炵幇銆傚湪澶ч儴鍒嗙殑鏃跺欙紝榪欑榪愯鏃舵垚鏈兘鏄井涓嶈凍閬撶殑銆備絾鏄紝鏈夋椂瀹冧滑鍗翠笉鑳芥弧瓚充綘鐨勮姹傘傛棦鏄槸鍦ㄧ紪璇戞湡鍙互鍐沖畾鍏跺垎鏀紝緙栬瘧鍣ㄨ繕鏄細鍕ゅ姵鐨勪負浣犵紪璇戝叾鎵鏈夌殑鍒嗘敮錛岃繖涔熷氨鎰忓懗鐫
if-else
鐨勬墍鏈夊垎鏀繀欏昏鎴愬姛緙栬瘧銆傛湁浜涘洶鎯戯紵緇х畫鐪嬩笅鍘伙細
鑰冭檻涓嬮潰鐨勬儏褰細浣犺璁′簡涓涓硾鍨嬪鍣?/span>
NiftyContainer
錛?/span>
template
<class T> class NiftyContainer {
聽聽聽 ...
};
浠?/span>
NiftyContainer
瀹瑰櫒鍖呭惈鎸囧悜
T
瀵硅薄鐨勬寚閽堛備負浜嗗鍒?/span>
NiftyContainer
涓殑涓涓璞★紝浣犲彲鑳介渶瑕佽皟鐢?/span>
T
鐨勬嫹璐濇瀯閫犲嚱鏁幫紙瀵逛簬闈炲鎬佺被鍨嬶級鎴栬呬竴涓悕涓?/span>
Clone()
鐨勮櫄鍑芥暟錛堝浜庡鎬佺被鍨嬶級銆備綘鍙互閫氳繃璁劇疆涓涓?/span>
bool
綾誨瀷鐨勬ā鐗堝弬鏁版潵浠庣被鐨勫鎴鋒墜閲岃幏寰楀叧浜庡鎬佺殑淇℃伅銆?/span>
template
<class T, bool isPolymorphic> class NiftyContainer {
聽聽聽
// Other actions
聽聽聽
void DoSomething() {
聽聽聽聽聽聽 T* pSomeObj = ...;
聽聽聽聽聽聽
if(isPolymorphic) {
聽聽聽聽聽聽聽聽聽聽 T* pNewObj = pSomeObj->Clone();
聽聽聽聽聽聽聽聽聽聽
// Some polymorphic algorithm
聽聽聽聽聽聽 }
聽聽聽聽聽聽
else {
聽聽聽聽聽聽聽聽聽聽 T* pNewObj = new T(*pSomeObj);
聽聽聽聽聽聽聽聽聽聽
// Some non-polymorphic algorithm
聽聽聽聽聽聽 }
聽聽聽 }
};
闂鍦ㄤ簬緙栬瘧鍣ㄤ笉浼氳浣犱莖騫哥紪璇戜笂闈㈢殑浠g爜銆備緥濡傦紝濡傛灉涓涓鎬佺被鍨嬫病鏈夊畾涔?/span>
Clone()
錛岄偅涔?/span>
NiftyContainer::DoSomething
緇濆涓嶄細閫氳繃緙栬瘧銆傚敖綆″湪緙栬瘧鏃舵垜浠偗瀹氬彲浠ュ浜庡垎鏀繘琛屽垽鏂紝浣嗚繖姣曠珶涓嶆槸緙栬瘧鍣ㄧ殑宸ヤ綔錛屼粬鍙細鍕ゅ姵鐨勪負浣犵紪璇戝嚭鎵鏈夌殑浠g爜銆備簬鏄綋浣犺瘯鍥捐皟鐢?/span>
NiftyContainer<int, false>::DoSomething
鐨勬椂鍊欙紝緙栬瘧鍣ㄨ繕鏄細鍋滃湪
pObj->Clone()
涓婏紝騫朵笖鎶辨ㄨ錛氣滀綘鍦ㄥ仛浠涔堬紵鈥?/span>
瀵逛簬闈炲鎬佺被鍨嬪垎鏀紝涔熸湁鍙兘鍙戠敓緙栬瘧閿欒銆傚鏋?/span>
T
鏄竴涓鎬佺被鍨嬶紝騫朵笖鎶婂畠鐨勬嫹璐濇瀯閫犲嚱鏁拌瀹氫負
private
鐨勬椂鍊欙紙榪欐椂涓涓鎬佺被鐨勮壇濂借涓猴級錛岄潪澶氭佸垎鏀殑
new T(*pObj)
灝變細鍙戠敓閿欒銆?/span>
浣犲彲鑳戒細鎯籌紝濡傛灉緙栬瘧鍣ㄥ彲浠ヤ笉鍘葷悊浼氶偅浜涗笉蹇呰鐨勫垎鏀氨濂戒簡錛屼絾鏄湅鏉ヤ笉澶彲鑳姐傞偅涔堬紝濡備綍鏄ソ鍛紵
鍏跺疄錛屾柟娉曟湁寰堝錛?/span>
Int2Type
鎻愪緵浜嗕竴涓畝媧佺殑鍔炴硶銆傚畠鍙互鏍規嵁
true
鍜?/span>
false
鏉ョ敓鎴愪袱涓笉鍚岀殑綾誨瀷錛岃屽悗鏍規嵁
Int2Type<isPolymorphic>
璇勪及姝g‘鐨勮皟鐢ㄣ?/span>
template
<class T, bool isPolymorphic> class NiftyContainer {
private
:
聽聽聽
// Other actions
聽聽聽
void DoSomething(T* pObj, Int2Type<true>) {
聽聽聽聽聽聽 T* pNewObj = pSomeObj->Clone();
聽聽聽聽聽聽
// Some polymorphic algorithm
聽聽聽 }
聽聽聽
void DoSomething(T* pObj, Int2Type<false>) {
聽聽聽聽聽聽 T* pNewObj = new T(*pSomeObj);
聽聽聽聽聽聽
// Some non-polymorphic algorithm
聽聽聽 }
public
:
聽聽聽
void DoSomething(T* pObj) {
聽聽聽聽聽聽 DoSomething(pObj, Int2Type<isPolymorphic>());
聽聽聽 }
};
褰撲綘鎯蟲妸甯告暣鏁扮敤浣滀竴涓被鍨嬬殑鏃跺欙紝
Int2Type
鏄潪甯告柟渚跨殑銆備綘鍙互浼犻掍竴涓復鏃剁殑鍙橀噺鏉ラ噸杞藉嚱鏁般傝屼箣鎵浠ユ垜浠彲浠ヨ繖鏍峰仛錛屾槸鍥犱負緙栬瘧鍣ㄤ笉浼氬幓緙栬瘧娌℃湁鐢ㄥ埌鐨勬ā鏉垮嚱鏁般?/span>
class涓嶆槸絀虹殑錛?span lang="EN-US">C++浼氬湪浣曟椂鍋氫簺浠涔堜簨鎯咃紵濡傛灉浣犱笉澹版槑瀹冧滑錛岀紪璇戝櫒浼氫負浣犲0鏄庡畠浠嚜宸辯殑鎷瘋礉鏋勯犲嚱鏁般佷竴涓祴鍊艱繍綆楃鍜屼竴涓瀽鏋勫嚱鏁般傚彟澶栵紝濡傛灉浣犱笉澹版槑涓涓瀯閫犲嚱鏁幫紝緙栬瘧鍣ㄨ繕浼氫負浣犲垱寤轟竴涓傛墍鏈夎繖浜涜嚜鍔ㄧ敓鎴愮殑鍑芥暟閮芥槸public鍜?span lang="EN-US">inline鐨勩備緥濡傦紝濡傛灉浣犲啓涓嬶細
class
Empty {};
榪欏拰浣犲啓涓嬪涓嬬殑浠g爜鏈川涓婃槸涓鏍風殑錛?/span>
class
Empty {
聽聽聽 Empty() {鈥 // default constructor
聽聽聽 Empty(const Empty& rhs) {鈥 // Copy constructor
聽聽聽 ~Empty() {鈥聽 // destructor - whether it's virtual?
聽聽聽
聽聽聽
// copy assignment operator
聽聽聽 Empty& operator=(const Empty& rhs) {}
}
褰撶劧錛岃繖浜涘嚱鏁板彧鏈夊畠浠湡姝h闇瑕佺殑鏃跺欐墠浼氳鍒涘緩銆備笅闈㈣繖浜涙儏鍐典細浣垮緱榪欎簺鍑芥暟琚垱寤猴細
Empty e1; // default constructor & destructor
Empty e2(e1); // copy constructor
e2 = e1; // copy assignment operator
鏃㈢劧緙栬瘧鍣ㄤ細涓轟綘鍒涘緩榪欎簺鍑芥暟錛岄偅涔堣繖浜涘嚱鏁伴兘鍋氫簺浠涔堝伐浣滃憿錛熼粯璁ょ殑鏋勯犲拰鏋愭瀯鍑芥暟涓昏鏄緙栬瘧鍣ㄦ斁緗竴浜涙墽琛屸滃箷鍚庡伐浣溾濈殑浠g爜錛屼緥濡傝皟鐢ㄥ熀綾誨拰闈為潤鎬佹暟鎹垚鍛樼殑鏋勯犲拰鏋愭瀯鍑芥暟絳夈傞渶瑕佹敞鎰忕殑鏄紪璇戝櫒涓轟綘鐢熸垚鐨勮繖涓瀽鏋勫嚱鏁板茍涓嶆槸铏氭嫙鐨勶紝闄ら潪榪欎釜綾葷殑鍩虹被鏄庣‘澹版槑浜嗕竴涓櫄鎷熺殑鏋愭瀯鍑芥暟銆?span lang="EN-US">
瀵逛簬鎷瘋礉鏋勯犲嚱鏁板拰璧嬪艱繍綆楃錛岀紪璇戝櫒鐢熸垚鐨勭増鏈彧鏄畝鍗曠殑copy姣忎竴涓潪闈欐佹暟鎹垚鍛樸備緥濡傦紝鑰冭檻涓涓悕涓?span lang="EN-US">NamedObject鐨勬ā鏉?span lang="EN-US">,瀹冨彲浠ヨ浣犳妸鍚嶅瓧鍜岀被鍨?span lang="EN-US">T鍏寵仈璧鋒潵銆?/font>
template
<typename T>
class
NamedObject {
public
:
聽聽聽 NamedObject(constchar* name, const T& value);
聽聽聽 NamedObject(const std::string& name, const T& value);
private
:
聽聽聽 std::string nameValue;
聽聽聽 T objectValue;
};
鐢變簬NamedObject涓0鏄庝簡鏋勯犲嚱鏁幫紝緙栬瘧鍣ㄤ究涓嶄細鍐嶈嚜鍋氫富寮犱負浣犵敓鎴愪竴涓粯璁ょ殑銆傝繖鏄緢閲嶈鐨勩傝繖鎰忓懗鐫濡傛灉浣犵簿蹇冭璁$殑綾葷殑鏋勯犳柟寮忥紝浣犲氨涓嶇敤鍐嶅幓鎷呭績緙栬瘧鍣ㄤ細鎰氳牏鐨勪負浣犳坊鍔犱竴涓笉甯﹀弬鏁扮殑鏋勯犲嚱鏁拌岀牬鍧忎綘鐨勮璁°?span lang="EN-US">
NamedObject
涓棦娌℃湁澹版槑鎷瘋礉鏋勯犲嚱鏁頒篃娌℃湁澹版槑璧嬪艱繍綆楃錛屾墍浠ュ綋闇瑕佺殑鏃跺欙紝緙栬瘧鍣ㄤ細鑷姩涓轟綘鐢熸垚銆傛樉鐒訛紝涓嬮潰鐨勪唬鐮侀渶瑕佹嫹璐濇瀯閫犲嚱鏁扮殑鏀寔錛?span lang="EN-US">
NamedObject<int> no1("Smallest Prime Number", 2);
NamedObject<int> no2(no1);
no1.nameValue鍜?span lang="EN-US">no1.objectValue鏉ュ垵濮嬪寲no2涓搴旂殑鎴愬憳銆傜敱浜?span lang="EN-US">nameValue鐨勭被鍨嬫槸string錛屽茍涓旀爣鍑嗙殑string鏈変竴涓嫹璐濇瀯閫犲嚱鏁幫紝鎵浠?span lang="EN-US">no2.nameValue灝卞彲浠ラ氳繃string鐨勬嫹璐濇瀯閫犲嚱鏁板畬鎴愩傚彟澶?span lang="EN-US">objectValue鏄竴涓暣鏁幫紝瀵逛簬榪欎釜鍐呯疆綾誨瀷錛岀畝鍗曠殑bit-copy灝卞彲浠ュ畬鎴愬鍒剁殑浠誨姟浜嗐?span lang="EN-US">
NamedObject
NamedObject錛?span lang="EN-US">
template
<typename T>
class
NamedObject {
public
:
聽聽聽 NamedObject(const std::string& name, const T& value);
private
:
聽聽聽 std::string& nameValue;
聽聽聽
const T objectValue;
};
涔嬪悗錛屼笅闈㈢殑浠g爜浼氭庢牱鍛紵
std::string newDog("Persephone");
std::string oldDog("Satch");
NamedObject<int> p(newDog, 2);
NamedObject<int> s(oldDog, 36);
p = s; // What should happen?
p.nameValue鍜?span lang="EN-US">s.nameValue鍒嗗埆鎸囧悜涓嶅悓鐨?span lang="EN-US">string瀵硅薄銆傝繖涓鍒跺簲璇ュp.nameValue鍋氭庢牱鐨勬敼鍙樺憿錛熺洿瑙変笂錛?span lang="EN-US">p.nameValue灝嗕細鎸囧悜s.nameValue鎵鎸囩殑string瀵硅薄銆備絾鏄繖鐮村潖浜?span lang="EN-US">C++鐨勪竴鏉″熀鏈殑鍑嗗垯錛?span lang="EN-US">C++涓嶅厑璁稿紩鐢ㄦ寚鍚戜笉鍚岀殑瀵硅薄銆傛崲鍙ヨ瘽璇達紝闅鵑亾鏀瑰彉p.nameValue鎵寮曠敤鐨勫璞″簲璇ヨ褰卞搷鍒板叾瀹冨璞℃墍寮曠敤鐨勫瓧絎︿覆鍚楋紵榪欐槸緙栬瘧鍣ㄧ敓鎴愮殑璧嬪艱繍綆楃搴旇鍋氱殑浜嬫儏鍚楋紵
瀵逛簬榪欎釜闂鐨勮В絳旀柟娉曟槸鎷掔粷緙栬瘧榪欐牱鐨勪唬鐮併傚鏋滀綘鎯寵鍚湁寮曠敤鏁版嵁鎴愬憳鐨勭被鏀寔璧嬪煎姛鑳斤紝閭d箞浣犲氨蹇呴』鑷繁瀹氫箟璧嬪艱繍綆楃銆傚浜庡惈鏈?font face="鏂板畫浣?>const鏁版嵁鎴愬憳鐨勭被鏉ヨ錛屾晠浜嬫槸綾諱技鐨勩備慨鏀瑰璞′腑鐨?span lang="EN-US">const鎴愬憳鎬繪槸闈炴硶鐨勶紝鎵浠ョ紪璇戝櫒瀵逛簬濡備綍澶勭悊榪欑闂涓鏃犳墍鐭ャ傛渶鍚庯紝濡傛灉鍩虹被鎶?span lang="EN-US">operator=澹版槑涓?span lang="EN-US">private錛岄偅涔堢紪璇戝櫒鍚屾牱浼氭嫆緇濅負媧劇敓綾葷敓鎴?span lang="EN-US">operator=銆傛瘯绔燂紝涓鏂歸潰錛屽嵆渚跨紪璇戝櫒鍙互鐢熸垚錛?span lang="EN-US">operator=涔熷彧鑳藉鐞嗘淳鐢熺被涓睘浜庡熀綾葷殑閭d竴閮ㄥ垎錛涘彟涓鏂歸潰錛屾淳鐢熺被涔熸牴鏈棤鏉冭闂熀綾諱腑鐨?span lang="EN-US">private鎴愬憳銆?span lang="EN-US">
l
聽聽聽聽聽聽聽聽
operator=鍜屾瀽鏋勫嚱鏁般?span lang="EN-US">