锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 涓句釜渚嬪瓙璇存槑铏氬嚱鏁般佸鎬併佹棭緇戝畾鍜屾櫄緇戝畾錛?br>
鏉庢皬涓ゅ厔濡癸紙鍝ュ摜鍜屽濡癸級鍙傚姞濮撴皬榪愬姩浼氾紙涓嶅悓濮撴皬緇勯槦鍙傚姞錛夛紝鍝ュ摜鐢峰瓙欏圭洰姣旇禌錛屽濡瑰弬鍔犲コ瀛愰」鐩瘮璧涳紝寮騫曞紡鏈変竴涓弬璧涢槦浼嶄唬琛ㄥ彂璦浠紡錛屽厔濡逛咯閮芥兂
鍘婚湶闇茶劯錛屽彲鍙兘涓浜哄幓錛屾渶緇堜粬浠喅瀹氬埌鏃舵姄闃勫喅瀹氾紝鑰岀粍濮斾細涔熶笉鍙嶅錛屽畠鎵嶄笉鍏沖績鏄摜鍝ヨ繕鏄濡規潵鍙戣█錛屽彧瑕佹淳涓涓鏉庣殑鏉ヨ涓ゅ彞璇濆氨琛屻傝繍鍔ㄤ細濡傛湡涓?
琛岋紝濡瑰鎶撻槃鑾峰緱浠h〃鏉庡鍙戣█鐨勬満浼氾紝鍝ュ摜鍙傚姞浜嗙敺瀛愰」鐩瘮璧涳紝濡瑰鍙傚姞浜嗗コ瀛愰」鐩瘮璧涖傛瘮璧涚粨鏋滃氨涓嶆槸鎴戜滑鍏沖績鐨勪簡銆?br> 鐜板湪璁╂垜浠潵鍋氫釜綾繪瘮錛堝彧璁ㄨ涓庤繍鍔ㄤ細鐩稿叧鐨勮瘽棰橈級錛?br> 錛?錛夌被鐨勮璁★細 浣嗘効榪欎釜姣斿柣璇存竻妤氫簡铏氬嚱鏁般佸鎬併佹棭緇戝畾鍜屾櫄緇戝畾鐨勬蹇靛拰瀹冧滑涔嬮棿鐨勫叧緋匯傚啀璇翠竴涓嬶紝鏃╃粦瀹氭寚緙栬瘧鍣ㄥ湪緙栬瘧鏈熼棿鍗崇煡閬撳璞$殑鍏蜂綋綾誨瀷騫剁‘瀹氭瀵硅薄璋冪敤鎴愬憳鍑芥暟鐨勭‘鍒囧湴鍧錛涜屾櫄緇戝畾鏄牴鎹寚閽堟墍鎸囧璞$殑綾誨瀷淇℃伅寰楀埌綾葷殑铏氬嚱鏁拌〃鎸囬拡榪涜岀‘瀹氳皟鐢ㄦ垚鍛樺嚱鏁扮殑紜垏鍦板潃銆?br> 2銆佹彮瀵嗘櫄緇戝畾鐨勭瀵?/p>
緙栬瘧鍣ㄥ埌搴曞仛浜嗕粈涔堝疄鐜扮殑铏氬嚱鏁扮殑鏅氱粦瀹氬憿錛熸垜浠潵鎺釜絀剁珶銆?/p>
緙栬瘧鍣ㄥ姣忎釜鍖呭惈铏氬嚱鏁扮殑綾誨垱寤轟竴涓〃錛堢О涓篤 TA B L E錛夈傚湪V TA B L E涓紝緙栬瘧鍣ㄦ斁緗壒瀹氱被鐨勮櫄鍑芥暟鍦板潃銆傚湪姣忎釜甯︽湁铏氬嚱鏁扮殑綾?
涓紝緙栬瘧鍣ㄧ瀵嗗湴緗竴鎸囬拡錛岀О涓簐 p o i n t e r錛堢緝鍐欎負V P T R錛夛紝鎸囧悜榪欎釜瀵硅薄鐨刅 TA B L E銆?span style="color: #000000;">閫氳繃鍩虹被鎸囬拡鍋氳櫄鍑芥暟璋?鐢ㄦ椂錛堜篃灝辨槸鍋氬鎬佽皟鐢ㄦ椂錛夛紝緙栬瘧鍣ㄩ潤鎬佸湴鎻掑叆鍙栧緱榪欎釜V P T R錛屽茍鍦╒ TA B L E琛ㄤ腑鏌ユ壘鍑芥暟鍦板潃鐨勪唬鐮侊紝榪欐牱灝辮兘璋冪敤姝g‘鐨勫嚱鏁頒嬌鏅氭崋緇戝彂鐢熴?/span>涓烘瘡涓被璁劇疆V TA B L E銆佸垵濮嬪寲V P T R銆佷負铏氬嚱鏁拌皟鐢ㄦ彃鍏ヤ唬鐮侊紝鎵鏈夎繖浜涢兘鏄嚜鍔ㄥ彂鐢熺殑錛屾墍浠ユ垜浠笉蹇呮媴蹇冭繖浜涖傚埄鐢ㄨ櫄鍑芥暟錛?榪欎釜瀵硅薄鐨勫悎閫傜殑鍑芥暟灝辮兘琚皟鐢紝鍝曞湪緙栬瘧鍣ㄨ繕涓嶇煡閬撹繖涓璞$殑鐗瑰畾綾誨瀷鐨勬儏鍐典笅銆傦紙銆奀++緙栫▼鎬濇兂銆?/span>錛?/p>
鈥斺斺斺旇繖孌佃瘽綰㈣壊鍔犵矖閮ㄥ垎浼間箮鏈夌偣闂錛屾垜涓漢鐨勭悊瑙g湅鍚庨潰鐨勬葷粨銆?/span> 鍦ㄤ換浣曠被涓笉瀛樺湪鏄劇ず鐨勭被鍨嬩俊鎭紝鍙璞′腑蹇呴』瀛樻斁綾諱俊鎭紝鍚﹀垯綾誨瀷涓嶅彲鑳藉湪榪愯鏃跺緩绔嬨傞偅榪欎釜綾諱俊鎭槸浠涔堝憿錛熸垜浠潵鐪嬩笅闈㈠嚑涓被錛?/p>
class no_virtual class one_virtual class two_virtual 浠ヤ笂涓変釜綾諱腑錛?br> no_virtual娌℃湁铏氬嚱鏁幫紝sizeof(no_virtual)=4錛岀被no_virtual鐨勯暱搴﹀氨鏄叾鎴愬憳鍙橀噺鏁村瀷a鐨勯暱搴︼紱 榪欎釜VPTR灝卞彲浠ョ湅浣滅被鐨勭被鍨嬩俊鎭?/p>
閭f垜浠潵鐪嬬湅緙栬瘧鍣ㄦ槸鎬庝箞寤虹珛VPTR鎸囧悜鐨勮繖涓櫄鍑芥暟琛ㄧ殑銆傚厛鐪嬩笅闈袱涓被錛?br> class base class derived : public base 涓や釜綾籚PTR鎸囧悜鐨勮櫄鍑芥暟琛紙VTABLE錛夊垎鍒涓嬶細 涓漢鎬葷粨濡備笅錛?/span> VPTR
甯稿父浣嶄簬瀵硅薄鐨勫紑澶達紝緙栬瘧鍣ㄨ兘寰堝鏄撳湴鍙栧埌VPTR鐨勫鹼紝浠庤岀‘瀹歏TABLE鐨勪綅緗俈PTR鎬繪寚鍚慥TABLE鐨勫紑濮嬪湴鍧錛屾墍鏈夊熀綾誨拰瀹冪殑瀛愮被鐨勮櫄鍑?
鏁板湴鍧錛堝瓙綾昏嚜宸卞畾涔夌殑铏氬嚱鏁伴櫎澶栵級鍦╒TABLE涓瓨鍌ㄧ殑浣嶇疆鎬繪槸鐩稿悓鐨勶紝濡備笂闈ase綾誨拰derived綾葷殑VTABLE涓璿fun1鍜寁fun2
鐨勫湴鍧鎬繪槸鎸夌浉鍚岀殑欏哄簭瀛樺偍銆傜紪璇戝櫒鐭ラ亾vfun1浣嶄簬VPTR澶勶紝vfun2浣嶄簬VPTR+1澶勶紝鍥犳鍦ㄧ敤鍩虹被鎸囬拡璋冪敤铏氬嚱鏁版椂錛岀紪璇戝櫒棣栧厛鑾峰彇鎸囬拡鎸?
鍚戝璞$殑綾誨瀷淇℃伅錛圴PTR錛夛紝鐒跺悗灝卞幓璋冪敤铏氬嚱鏁般傚涓涓猙ase綾繪寚閽坧Base鎸囧悜浜嗕竴涓猟erived瀵硅薄錛岄偅pBase->vfun2
()琚紪璇戝櫒緲昏瘧涓?nbsp;VPTR+1 鐨勮皟鐢紝鍥犱負铏氬嚱鏁皏fun2鐨勫湴鍧鍦╒TABLE涓綅浜庣儲寮曚負1鐨勪綅緗笂銆傚悓鐞嗭紝pBase->vfun3
()琚紪璇戝櫒緲昏瘧涓?nbsp;VPTR+2鐨勮皟鐢ㄣ傝繖灝辨槸鎵璋撶殑鏅氱粦瀹氥?/p>
鎴戜滑鏉ョ湅涓涓嬭櫄鍑芥暟璋冪敤鐨勬眹緙栦唬鐮侊紝浠ュ姞娣辯悊瑙c?/p>
void test(base* pBase) int main(int argc, char* argv[]) derived td;緙栬瘧鐢熸垚鐨勬眹緙栦唬鐮佸涓嬶細 pBase->vfun2();緙栬瘧鐢熸垚鐨勬眹緙栦唬鐮佸涓嬶細 鐜板湪搴旇瀵瑰鎬併佽櫄鍑芥暟銆佹櫄緇戝畾鏈夋瘮杈冩竻妤氱殑浜嗚В浜嗗惂銆?br>
]]>
]]>
鏉庢皬鍏勫灞炰簬鏉庢皬瀹舵棌錛屾潕姘忔槸鍩虹被錛堣繖閲岃繕鏄娊璞$殑綰熀綾伙級錛屾潕姘忓張媧劇敓鍑轟袱涓瓙綾伙紙鏉庢皬鐢峰拰鏉庢皬濂籌級錛屾潕姘忕敺浼氭墍鏈夌敺瀛愰」鐩殑姣旇禌錛堟潕姘忕敺鐨勬垚鍛樺嚱
鏁幫級錛屾潕姘忓コ浼氭墍鏈夊コ瀛愰」鐩殑姣旇禌錛堟潕姘忓コ鐨勬垚鍛樺嚱鏁幫級銆傚鏉庣殑浜洪兘浼氬彂璦錛堝熀綾昏櫄鍑芥暟錛夛紝鏉庢皬鐢峰拰鏉庢皬濂崇戶鎵胯嚜鏉庢皬褰撶劧涔熶細鍙戣█錛屽彧鏄敺濂寵璇濆0闊充笉涓
鏍鳳紝鍐呭涔熶細鍙堝樊寮傦紝緇欎漢鎰熻涓嶅悓錛堟潕姘忕敺鍜屾潕姘忓コ鍒嗗埆閲嶆柊瀹氫箟鍙戣█榪欎釜铏氬嚱鏁幫級銆傛潕姘忎袱鍏勫灝辨槸鏉庢皬鐢峰拰鏉庢皬濂充袱涓被鐨勫疄浣撱?br> 錛?錛夌▼搴忚璁★細
鏉庢皬鍏勫濉啓鍙傝禌鎶ュ悕琛ㄣ?br> 錛?錛夌紪璇戯細
鏉庢皬鍏勫鐨勫弬璧涙姤鍚嶈〃琚笂浜ょ粰緇勫浼氾紙緙栬瘧鍣級錛屽摜鍝ュ拰濡瑰鍒嗗埆鍙傚姞鐢峰瓙鍜屽コ瀛愮殑姣旇禌錛岀粍濮斾細涓鐪嬪氨鏄庣櫧浜嗭紙鏃╃粦瀹氾級錛屽彧鏄彂璦浜洪変笉鏄庣‘錛岀粍濮斾細鐪嬪埌鎶?
鍚嶈〃涓婂啓鐨勬槸“鏉庡浠h〃”錛堝熀綾繪寚閽堬級錛岀粍濮斾細涓嶈兘紜畾鍒板簳鏄皝錛屽氨鍋氫簡涓娉細濡傛灉鏄敺鐨勶紝灝辨槸鍝ュ摜鏉庢煇鏌愶紱濡傛灉鏄コ鐨勶紝灝辨槸濡瑰鏉庢煇鏌愶紙鏅氱粦瀹氾級銆傜粍
濮斾細鍋氬ソ鍏跺畠鍑嗗宸ヤ綔鍚庯紝灝辯瓑榪愬姩浼氬紑濮嬩簡錛堢紪璇戝畬姣曪級銆?br> 錛?錛夌▼搴忚繍琛岋細
榪愬姩浼氬紑濮嬩簡錛堢▼搴忓紑濮嬭繍琛岋級錛屽紑騫曞紡涓婃垜浠惉鍒頒簡鏉庡濡瑰鐨勫彂璦錛屽鏋滄槸鍝ュ摜榪愭皵濂芥姄闃勮儨鍑猴紝鎴戜滑灝嗗惉鍒板摜鍝ョ殑鍙戣█錛堝鎬侊級銆傜劧鍚庡氨鏄湅鍒板厔濡逛咯鍙傚姞姣旇禌浜嗐傘傘?/p>
{
public:
void fun1() const{}
int fun2() const { return a; }
private:
int a;
}
{
public:
virtual void fun1() const{}
int fun2() const { return a; }
private:
int a;
}
{
public:
virtual void fun1() const{}
virtual int fun2() const { return a; }
private:
int a;
}
one_virtual鏈変竴涓櫄鍑芥暟錛宻izeof(one_virtual)=8錛?br> two_virtual
鏈変袱涓櫄鍑芥暟錛宻izeof(two_virtual)=8錛?nbsp;鏈変竴涓櫄鍑芥暟鍜屼袱涓櫄鍑芥暟鐨勭被鐨勯暱搴︽病鏈夊尯鍒紝鍏跺疄瀹冧滑鐨勯暱搴﹀氨鏄痭o_virtual鐨?
闀垮害鍔犱竴涓獀oid鎸囬拡鐨勯暱搴︼紝瀹冨弽鏄犲嚭錛屽鏋滄湁涓涓垨澶氫釜铏氬嚱鏁幫紝緙栬瘧鍣ㄥ湪榪欎釜緇撴瀯涓彃鍏ヤ竴涓寚閽堬紙 V P T R錛夈傚湪one_virtual 鍜?
two_virtual涔嬮棿娌℃湁鍖哄埆銆傝繖鏄洜涓篤 P T R鎸囧悜涓涓瓨鏀懼湴鍧鐨勮〃錛屽彧闇瑕佷竴涓寚閽堬紝鍥犱負鎵鏈夎櫄鍑芥暟鍦板潃閮藉寘鍚湪榪欎釜琛ㄤ腑銆?/p>
{
public:
void bfun(){}
virtual void vfun1(){}
virtual int vfun2(){}
private:
int a;
}
{
public:
void dfun(){}
virtual void vfun1(){}
virtual int vfun3(){}
private:
int b;
}
base綾?br> 鈥斺斺斺斺斺?br> VPTR鈥斺?gt; |&base::vfun1 |
鈥斺斺斺斺斺?br> |&base::vfun2 |
鈥斺斺斺斺斺?br>
derived綾?br> 鈥斺斺斺斺斺斺?br> VPTR鈥斺?gt; |&derived::vfun1 |
鈥斺斺斺斺斺斺?br> |&base::vfun2 |
鈥斺斺斺斺斺斺?br> |&derived::vfun3 |
鈥斺斺斺斺斺斺?br>
姣忓綋鍒涘緩涓涓寘鍚湁铏氬嚱鏁扮殑綾繪垨浠庡寘鍚湁铏氬嚱鏁扮殑綾繪淳鐢熶竴涓被鏃訛紝緙栬瘧鍣ㄥ氨涓鴻繖涓被鍒涘緩涓涓猇TABLE錛屽涓婂浘鎵紺恒傚湪榪欎釜琛ㄤ腑錛岀紪璇戝櫒鏀劇疆浜嗗湪榪欎釜綾?
涓垨鍦ㄥ畠鐨勫熀綾諱腑鎵鏈夊凡澹版槑涓簐irtual鐨勫嚱鏁扮殑鍦板潃銆傚鏋滃湪榪欎釜媧劇敓綾諱腑娌℃湁瀵瑰湪鍩虹被涓0鏄庝負virtual鐨勫嚱鏁拌繘琛岄噸鏂板畾涔夛紝緙栬瘧鍣ㄥ氨浣跨敤鍩虹被
鐨勮繖涓櫄鍑芥暟鍦板潃銆傦紙鍦╠erived鐨刅TABLE涓紝vfun2鐨勫叆鍙e氨鏄繖縐嶆儏鍐點傦級鐒跺悗緙栬瘧鍣ㄥ湪榪欎釜綾諱腑鏀劇疆VPTR銆傚綋浣跨敤綆鍗曠戶鎵挎椂錛屽浜庢瘡
涓璞″彧鏈変竴涓猇PTR銆?span style="font-weight: bold; color: #ff0000;">VPTR蹇呴』琚垵濮嬪寲涓烘寚鍚戠浉搴旂殑VTABLE錛岃繖鍦ㄦ瀯閫犲嚱鏁頒腑鍙戠敓銆?/span>
涓鏃PTR琚垵濮嬪寲涓烘寚鍚戠浉搴旂殑VTABLE錛屽璞″氨"鐭ラ亾"瀹冭嚜宸辨槸浠涔堢被鍨嬨備絾鍙湁褰撹櫄鍑芥暟琚皟鐢ㄦ椂榪欑鑷垜璁ょ煡鎵嶆湁鐢ㄣ?/p>
1銆佷粠鍖呭惈铏氬嚱鏁扮殑綾繪淳鐢熶竴涓被鏃訛紝緙栬瘧鍣ㄥ氨涓鴻綾誨垱寤轟竴涓猇TABLE銆傚叾姣忎竴涓〃欏規槸璇ョ被鐨勮櫄鍑芥暟鍦板潃銆?br>2銆佸湪瀹氫箟璇ユ淳鐢熺被瀵硅薄鏃訛紝鍏堣皟鐢ㄥ叾鍩虹被鐨勬瀯閫犲嚱鏁幫紝鐒跺悗鍐嶅垵濮嬪寲VPTR錛屾渶鍚庡啀璋冪敤媧劇敓綾葷殑鏋勯犲嚱鏁幫紙
浠庝簩榪涘埗鐨勮閲庢潵鐪嬶紝鎵璋撳熀綾誨瓙綾繪槸涓涓ぇ緇撴瀯浣擄紝鍏朵腑this鎸囬拡寮澶寸殑鍥涗釜瀛楄妭瀛樻斁铏氬嚱鏁拌〃澶存寚閽堛傛墽琛屽瓙綾葷殑鏋勯犲嚱鏁扮殑鏃跺欙紝棣栧厛璋冪敤鍩虹被鏋勯犲嚱
鏁幫紝this鎸囬拡浣滀負鍙傛暟錛屽湪鍩虹被鏋勯犲嚱鏁頒腑濉叆鍩虹被鐨剉ptr錛岀劧鍚庡洖鍒板瓙綾葷殑鏋勯犲嚱鏁幫紝濉叆瀛愮被鐨剉ptr錛岃鐩栧熀綾誨~鍏ョ殑vptr銆傚姝や互鏉ュ畬鎴?
vptr鐨勫垵濮嬪寲銆?錛?br>3銆佸湪瀹炵幇鍔ㄦ佺粦瀹氭椂錛屼笉鑳界洿鎺ラ噰鐢ㄧ被瀵硅薄錛岃屼竴瀹氳閲囩敤鎸囬拡鎴栬呭紩鐢ㄣ傚洜涓洪噰鐢ㄧ被瀵硅薄浼犲兼柟寮忥紝鏈変復鏃跺熀綾誨璞$殑浜х敓錛岃岄噰鐢ㄦ寚閽堬紝鍒欐槸閫氳繃鎸囬拡鏉ヨ闂閮ㄧ殑媧劇敓綾誨璞$殑VPTR鏉ヨ揪鍒拌闂淳鐢熺被铏氬嚱鏁扮殑緇撴灉銆?
{
pBase->vfun2();
}
{
derived td;
test(&td);
return 0;
}
mov DWORD PTR _td$[esp+24], OFFSET FLAT:??_7derived@@6B@ ; derived::`vftable'
鐢辯紪璇戝櫒鐨勬敞閲婂彲鐭ワ紝姝ゆ椂PTR _td$[esp+24]涓瓨鍌ㄧ殑灝辨槸derived綾葷殑VTABLE鍦板潃銆?br>
test(&td);緙栬瘧鐢熸垚鐨勬眹緙栦唬鐮佸涓嬶細
lea eax, DWORD PTR _td$[esp+24]
mov DWORD PTR __$EHRec$[esp+32], 0
push eax
call ?test@@YAXPAVbase@@@Z ; test
璋冪敤test鍑芥暟鏃跺畬鎴愪簡濡備笅宸ヤ綔錛氬彇瀵硅薄td鐨勫湴鍧錛屽皢鍏跺帇鏍堬紝鐒跺悗璋冪敤test銆?/p>
mov ecx, DWORD PTR _pBase$[esp-4]
mov eax, DWORD PTR [ecx]
jmp DWORD PTR [eax+4]
棣栧厛浠庢爤涓彇鍑簆Base鎸囬拡鎸囧悜鐨勫璞″湴鍧璧嬬粰ecx錛岀劧鍚庡彇瀵硅薄寮澶寸殑鎸囬拡鍙橀噺涓殑鍦板潃璧嬬粰eax錛屾鏃秂ax鐨勫煎嵆涓篤PTR鐨勫鹼紝涔熷氨鏄?
VTABLE鐨勫湴鍧銆傛渶鍚庡氨鏄皟鐢ㄨ櫄鍑芥暟浜嗭紝鐢變簬vfun2浣嶄簬VTABLE鐨勭浜屼釜浣嶇疆錛岀浉褰撲簬 VPTR+1錛屾瘡涓嚱鏁版寚閽堟槸4涓瓧鑺傞暱錛屾墍浠ユ渶鍚庣殑
璋冪敤琚紪璇戝櫒緲昏瘧涓?nbsp;jmp DWORD PTR [eax+4]銆傚鏋滄槸璋冪敤pBase->vfun1()錛岃繖鍙ュ氨璇ヨ緙栬瘧涓?
jmp DWORD PTR [eax]銆?br>
]]>
using namespace std;
class Obstacle
{
public:
virtual void action()=0;
};
class Player
{
public:
virtual void interactWith(Obstacle*)=0;
};
class Kitty: public Player
{
virtual void interactWith(Obstacle *ob)
{
cout<<"Kitty has encountered a";
ob->action();
}
};
class KungFuGuy: public Player
{
virtual void interactWith(Obstacle* ob)
{
cout<<"KungFuGuy now battles against a";
ob->action();
}
};
class Puzzle: public Obstacle
{
public:
void action(){cout<<"Puzzle"<<endl;}
};
class NastyWeapon: public Obstacle
{
public:
void action(){cout<<"NastyWeapon"<<endl;}
};
//the abstract factory
class GameElementFactory
{
public:
virtual Player* makePlayer()=0;
virtual Obstacle* makeObstacle()=0;
};
//concreate factories
class KittiesAndPuzzles:public GameElementFactory
{
public:
virtual Player* makePlayer(){return new Kitty;}
virtual Obstacle * makeObstacle(){return new Puzzle;}
};
class KillAndDismember:public GameElementFactory
{
public:
virtual Player* makePlayer(){return new KungFuGuy;}
virtual Obstacle *makeObstacle(){return new NastyWeapon;}
};
class GameEnvironment
{
GameElementFactory* gef;
Player* p;
Obstacle *ob;
public:
GameEnvironment(GameElementFactory * factory)
:gef(factory),p(factory->makePlayer()),ob(factory->makeObstacle()){}
void play(){p->interactWith(ob);}
~GameEnvironment()
{
delete p;
delete ob;
delete gef;
}
};
int main()
{
GameEnvironment
g1(new KittiesAndPuzzles),
g2(new KillAndDismember);
g1.play();
g2.play();
}
鍦ㄦ鐜涓紝Player瀵硅薄涓嶰bstacle 瀵硅薄浜や簰錛屼絾鏄疨layer鍜孫bstacle綾誨瀷渚濊禆浜庡叿浣撶殑娓告垙銆傚彲浠ラ夋嫨鐗瑰畾鐨凣ameElementFactory鏉ュ喅瀹氭父鎴忕殑綾誨瀷錛岀劧鍚嶨ameEnvironment鎺у埗娓告垙鐨勮緗拰榪涜銆傚湪鏈緥涓紝娓告垙鐨勮緗拰榪涜寰堢畝鍗曪紝浣嗘槸閭d簺鍔ㄤ綔鍦ㄥ緢澶х▼搴︿笂鍐沖畾浜嗘父鎴忕殑緇撴灉銆?br>
]]>
#include<stdexcept>
#include<cstddef>
#include<string>
#include<vector>
using namespace std;
class Shape
{
public:
virtual void draw()=0;
virtual void erase()=0;
virtual ~Shape(){}
class BadShapeCreation :public logic_error
{
public:
BadShapeCreation(string type):
logic_error("Cannot create type"+type){}
};
static Shape* factory(const string &type)
throw(BadShapeCreation);
};
class Circle:public Shape
{
Circle(){}
friend class Shape;
public:
void draw(){cout<<"Circle::draw"<<endl;}
void erase(){cout<<"Circle::erase"<<endl;}
~Circle(){cout<<"Circle::~Circle"<<endl;}
};
class Square:public Shape
{
Square(){}
friend class Shape;
public:
void draw(){cout<<"Square::draw"<<endl;}
void erase(){cout<<"Square::erase"<<endl;}
~Square(){cout<<"Square::~Square"<<endl;}
};
Shape *Shape::factory(const string & type)
throw(Shape::BadShapeCreation)
{
if(type=="Circle")return new Circle;
if(type=="Square")return new Square;
throw BadShapeCreation(type);
}
char *sl[]={"Circle","Square","Square","Circle","Circle","Circle","Square"};
int main()
{
vector<Shape*>shapes;
try{
for(size_t i=0;i<sizeof sl/sizeof sl[0];i++)
shapes.push_back(Shape::factory(sl[i]));
}catch(Shape::BadShapeCreation e)
{
cout<<e.what()<<endl;
return -1;
}
for(size_t i=0;i<shapes.size();i++)
{
shapes[i]->draw();
shapes[i]->erase();
}
}
鍑芥暟factory 鍏佽浠ヤ竴涓弬鏁版潵鍐沖畾鍒涘緩浣曠綾誨瀷鐨凷hape銆傚湪榪欓噷錛屽弬鏁扮被鍨嬩負string,涔熷彲浠ユ槸浠諱綍鏁版嵁闆嗐備負浜嗙‘淇濆璞$殑鍒涘緩鍙兘鍙戠敓鍦ㄥ嚱鏁癴actory()涓紝Shape鐨勭壒瀹氱被鍨嬬殑鏋勯犲嚱鏁拌璁句負縐佹湁錛屽悓鏃禨hape琚0鏄庝負鍙嬪厓綾伙紝鍥犳factory()鑳藉璁塊棶榪欎簺鏋勯犲嚱鏁般?br>
鍙傝冿細 C++緙栫▼鎬濇兂鍗?
]]>
#include<iostream>
#include<vector>
using namespace std;
enum Answer{NO,YES};
class GimmeStrategy
{
public:
virtual Answer canIHave()=0;
virtual ~GimmeStrategy(){}
};
class AskMom: public GimmeStrategy
{
public:
Answer canIHave()
{
cout<<"Moom? can I have this?"<<endl;
return NO;
}
};
class AskDad: public GimmeStrategy
{
public:
Answer canIHave()
{
cout<<"Dad,I really need this!"<<endl;
return NO;
}
};
class AskGrandpa:public GimmeStrategy
{
public:
Answer canIHave()
{
cout<<"Grandpa , is it my birthday yet?"<<endl;
return NO;
}
};
class AskGrandma:public GimmeStrategy
{
public:
Answer canIHave()
{
cout<<"Grandma,I really love you!"<<endl;
return YES;
}
};
class Gimme:public GimmeStrategy
{
vector<GimmeStrategy*>chain;
public:
Gimme(){
chain.push_back(new AskMom());
chain.push_back(new AskDad());
chain.push_back(new AskGrandpa());
chain.push_back(new AskGrandma());
}
Answer canIHave()
{
vector<GimmeStrategy*>::iterator it=chain.begin();
while(it!=chain.end())
if((*it++)->canIHave()==YES)
return YES;
cout<<"whiiiiiinnne!"<<endl;
return NO;
}
~Gimme(){};
};
int main()
{
Gimme chain;
chain.canIHave();
}
鍙傝?錛歝++緙栫▼鎬濇兂鍗蜂簩
]]>
using namespace std;
class NameStrategy
{
public:
virtual void greet()=0;
};
class SayHi: public NameStrategy
{
public:
void greet()
{
cout<<"Hi! How's it going?"<<endl;
}
};
class Ignore: public NameStrategy
{
public:
void greet()
{
cout<<"Pretend I don't see you)"<<endl;
}
};
class Admission:public NameStrategy
{
public:
void greet()
{
cout<<"I'm sorry ,I forgot your name."<<endl;
}
};
class Context
{
NameStrategy & strategy;
public:
Context(NameStrategy & strat):strategy(strat){}
void greet(){strategy.greet();}
};
int main()
{
SayHi sayhi;
Ignore ignore;
Admission admission;
Context c1(sayhi),c2(ignore),c3(admission);
c1.greet();
c2.greet();
c3.greet();
}
Context::greet()鍙互姝h鍦板啓寰楁洿鍔犲鏉備簺錛屽畠綾諱技妯℃澘鏂規硶妯″紡錛屽洜涓哄叾涓寘鍚簡涓嶈兘鏀瑰彉鐨勪唬鐮併備絾鍦ㄥ嚱鏁癿ain()涓彲浠ョ湅鍒幫紝鍙互鍦ㄨ繍琛屾椂灝辯瓥鐣ヨ繘琛岄夋嫨銆傛洿榪涗竴姝ョ殑鍋氭硶銆傚彲浠ュ皢鐘舵佹ā寮忎笌Context瀵硅薄鐨勭敓瀛樻湡闂村彉鍖栫殑絳栫暐妯″紡緇撳悎璧鋒潵浣跨敤銆?br>
]]>
using namespace std;
class ApplicationFramework
{
protected :
virtual void customize1()=0;
virtual void customize2()=0;
public:
void templateMethod()
{
for(int i=0;i<5;i++)
{
customize1();
customize2();
}
}
};
class MyApp: public ApplicationFramework
{
protected:
void customize1(){cout<<"Hello";}
void customize2(){cout<<"World!"<<endl;}
};
int main()
{
MyApp app;
app.templateMethod();
}
鍙傝冿細c++緙栫▼鎬濇兂鍗蜂簩
]]>
瀹炰緥浠g爜濡備笅錛?br>//FibonacciGenerator.h, 鏂愭嘗閭e鏁板垪浜х敓鍣ㄧ被
#ifndef FIBONACCIGENERATOR_H
#define FIBONACCIGENERATOR_H
class FibonacciGenerator
{
int n;
int val[2];
public:
FibonacciGenerator():n(0){val[0]=val[1]=0;}
int operator()()
{
int result=n>2?val[0]+val[1]:n>0?1:0;
++n;
val[0]=val[1];
val[1]=result;
return result;
}
int count(){return n;}
};
#endif
涔熻璇昏呭笇鏈涘埄鐢ㄨ繖涓駭鐢熷櫒鏉ユ墽琛孲TL鏁板肩畻娉曟搷浣溿傞仐鎲劇殑鏄紝STL綆楁硶鍙兘浣跨敤榪唬鍣ㄦ墠鑳藉伐浣滐紝榪欏氨瀛樺湪鎺ュ彛涓嶅尮閰嶇殑闂銆傝В鍐蟲柟娉曞氨鏄駭鐢熶竴涓傞厤鍣ㄣ備唬鐮佸涓嬨?br>#include<iostream>
#include<numeric>
#include"FibonacciGenerator.h"
using namespace std;
class FibonacciAdapter
{
FibonacciGenerator f;
int length;
public:
FibonacciAdapter(int size):length(size){}
class iterator;
friend class iterator;
class iterator:public std::iterator<std::input_iterator_tag,FibonacciAdapter,ptrdiff_t>
{
FibonacciAdapter& ap;
public:
typedef int value_type;
iterator(FibonacciAdapter &a):ap(a){}
bool operator==(const iterator &)const{
return ap.f.count()==ap.length;
}
bool operator!=(const iterator &x)const
{
return !(*this==x);
}
int operator*()const{return ap.f();}
iterator& operator++(){return *this;}
iterator operator++(int){return *this;}
};
iterator begin(){return iterator(*this);}
iterator end(){return iterator(*this);}
};
int main()
{
const int SZ=20;
FibonacciAdapter a1(SZ);
cout<<"accumulate:"<<accumulate(a1.begin(),a1.end(),0)<<endl;
}
]]>
#include<iostream>
using namespace std;
class ProxyBase
{
public:
virtual void f()=0;
virtual void g()=0;
virtual void h()=0;
virtual ~ProxyBase(){}
};
class Implementation :public ProxyBase
{
public:
void f(){cout<<"Implementation.f()"<<endl;}
void g(){cout<<"Implementation.g()"<<endl;}
void h(){cout<<"Implementation.h()"<<endl;}
};
class Proxy: public ProxyBase
{
ProxyBase *implementation;
public:
Proxy(){implementation=new Implementation();}
~Proxy(){delete implementation;}
void f(){implementation->f();}
void g(){implementation->g();}
void h(){implementation->h();}
};
int main()
{
Proxy p;
p.f();
p.g();
p.h();
}
錛?錛夌姸鎬佹ā寮?br>#include<iostream>
using namespace std;
class Creature
{
class State
{
public:
virtual string response()=0;
};
class Frog : public State
{
public:
string response(){return "Ribbet!";}
};
class Prince:public State
{
public:
string response(){return "Darling!";}
};
State *state;
public:
Creature(): state(new Frog()){}
void greet()
{
cout<<state->response()<<endl;
}
void kiss()
{
delete state;
state=new Prince();
}
};
int main()
{
Creature creature;
creature.greet();
creature.kiss();
creature.greet();
}
]]>
#include<vector>
using namespace std;
class Command
{
public:
virtual void execute()=0;
};
class Hello: public Command
{
public:
void execute(){cout<<"hello ";}
};
class World : public Command
{
public:
void execute(){cout<<"world!";}
};
class IAm:public Command
{
public:
void execute(){cout<<"I'm the command pattern!";}
};
class Macro
{
vector<Command *>commands;
public:
void add(Command *c){commands.push_back(c);}
void run()
{
vector<Command*>::iterator it=commands.begin();
while(it!=commands.end())
{
(*it++)->execute();
cout<<endl;
}
}
};
int main()
{
Macro macro;
macro.add(new Hello);
macro.add(new World);
macro.add(new IAm);
macro.run();
}
鍛戒護妯″紡鐨勪富瑕佺壒鐐規槸鍏佽鍚戜竴涓嚱鏁版垨鑰呭璞′紶閫掍竴涓兂瑕佺殑鍔ㄤ綔銆備笂榪頒緥瀛愭彁渚涗簡灝嗕竴緋誨垪闇瑕佷竴璧鋒墽琛岀殑鍔ㄤ綔闆嗚繘琛屾帓闃熺殑鏂規硶銆傚湪榪欓噷錛屽彲浠ュ姩鎬佸垱寤烘柊鐨勮涓猴紝鏌愪簺浜嬫儏閫氬父鍙兘閫氳繃緙栧啓鏂扮殑浠g爜鏉ュ畬鎴愶紝鑰屽湪涓婅堪渚嬪瓙涓彲浠ラ氳繃瑙i噴涓涓剼鏈潵瀹炵幇銆?br>
鍙傝冿細c++緙栫▼鎬濇兂2
]]>
鍗曚歡涔熻鏄渶綆鍗曠殑璁捐妯″紡錛屽畠鏄厑璁鎬竴涓被鏈変笖浠呮湁涓涓疄渚嬬殑鏂規硶銆傚垱寤轟竴涓崟浠舵ā寮忕殑鍏抽敭鏄槻姝㈠鎴風▼搴忓憳鑾峰緱浠諱綍鎺у埗鍏跺璞$敓瀛樻湡鐨勬潈鍒┿備負浜嗗仛鍒拌繖涓鐐癸紝澹版槑鎵鏈夌殑鏋勯犲嚱鏁頒負縐佹湁錛屽茍涓旈槻姝㈢紪璇戝櫒闅愬紡鐢熸垚浠諱綍鏋勯犲嚱鏁般傛敞鎰忥紝鎷瘋礉鏋勯犲嚱鏁板拰璧嬪兼搷浣滅錛堣繖涓や釜鏁呮剰娌℃湁瀹炵幇錛岋紝鍥犱負瀹冧滑鏍規湰涓嶄細琚皟鐢級琚0鏄庝負縐佹湁錛屼互渚塊槻姝換浣曡繖綾誨鍒跺姩浣滀駭鐢熴傝繖縐嶆柟娉曞茍娌℃湁闄愬埗鍙垱寤轟竴涓璞°傝繖縐嶆妧鏈篃鏀寔鍒涘緩鏈夐檺涓璞$殑瀵硅薄姹犮?br>
涓嬮潰鐨勭▼搴忔樉紺哄湪c++涓浣曞疄鐜頒竴涓崟浠舵ā寮?br>#include<iostream>
using namespace std;
class Singleton
{
static Singleton s;
int i;
Singleton(int x):i(x){}
Singleton & operator=(Singleton &); //disallowed
Singleton(const Singleton &);
public:
static Singleton & instance(){return s;}
int getValue(){return i;}
void setValue(int x){i=x;}
};
Singleton Singleton::s(47);
int main()
{
Singleton &s =Singleton::instance();
cout<<s.getValue()<<endl;
Singleton &s2=Singleton::instance();
s2.setValue(9);
cout<<s.getValue()<<endl;
}
鍙傝冿細c++ 緙栫▼鎬濇兂 2
]]>