锘??xml version="1.0" encoding="utf-8" standalone="yes"?> One of the interesting features I found in C# is a 錕紼vents and Delegates錕?concept. The idea is good but not new in Object Oriented Programming, it is one of the most frequently used concepts in programming, sometimes referred to as 錕絆bserver錕?or 錕紻ocument/View錕?design pattern. Classical formulation of it could be found in 錕紻esign Patterns, Elements of Reusable Object Oriented Software錕?by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (The Gang of Four). This concept is used when you want some information stored in one object, called 錕絤odel錕?(subject) to be watched by others, called 錕絭iews錕?(observers). Each time when information is changed in the 錕絤odel錕? 錕絭iews錕?attached to the model should receive notification and update there states accordingly to the changed 錕絤odel錕? Classical implementation described in 錕紻esign Patterns錕? As it is seen from the class diagram, concrete models should be derived from In many applications, this straightforward implementation is good enough, but things are getting ugly when you have different kinds of changes in the 錕絪ubject錕?and you want to pass different types of parameters to the 錕絭iews錕? One of the examples for complex 錕組odel錕?錕絍iew錕?relations is a GUI control attached to its processing function. Each time the control錕絪 state is changed, process function is called with parameters indicating new state of the control. These kinds of problems are solved in C# by the introduction of 錕紼vents and Delegates錕?concept. The resolution of the problem is easier in C#, because all classes are inherited from the same 錕給bject錕?class. At the beginning, I thought why we do not have this nice 錕紼vents and Delegates錕?thing in standard C++, but then I came to the conclusion that C++ does not need it. C++ language is powerful enough to express 錕紼vents錕?and 錕紻elegates錕?concept in terms of already existing primitives. Proposed design makes it possible to "connect" different methods with different number of parameters belonging to unrelated classes to the 錕絤odel錕? The keys for this solution are C++ templates (generic types) and pointes to member functions. Suppose we have a class Views represented by The final step is to create viewers Resulting output is: First of all, if we want to attach different types of event handles (member functions with same types of parameters from different classes) to the same event, we should provide common base for them. We use templates to make it generic for any combination of parameter types in 錕絛elegate錕?or call back method. There are different event types for every number of arguments in callback function. Specific type of member function pointer within a pointer to the object is stored in the derived class. Event class stores map of event handlers and notifies all of them when This implementation is quite similar to those in the article 錕紼mulating C# delegates in Standard C++錕?/font>. I found out it after I already wrote the article. Actually, the fact that we have a similar way to deal with the problem means that it錕絪 a very intuitive solution for this kind of problem in C++. An advantage of the current implementation is that it supports different number of arguments, so any member function of any class could be a callback (delegate). Probably to have this thing as a part of standard library is a good thing, but even if it錕絪 not a part of the standard, you can use it as it is. This implementation is restricted to events up to 3 parameters, it can be easily extended to other numbers by just rewriting it with different number of parameters (see code for details). 瀹氫箟瀵硅薄闂寸殑涓縐嶄竴瀵瑰鐨勪緷璧栧叧緋伙紝褰撲竴涓璞$殑鐘舵佸彂鐢熸敼鍙樻椂錛屾墍鏈変緷璧栦簬瀹冪殑瀵硅薄閮藉緱鍒伴氱煡騫惰鑷姩鏇存柊銆?/p>
UML緇撴瀯鍥撅細 瑙f瀽錛?/p>
Observer妯″紡瀹氫箟鐨勬槸涓縐嶄竴瀵瑰鐨勫叧緋伙紝榪欓噷鐨勪竴灝辨槸鍥句腑鐨凷ubject綾伙紝鑰屽鍒欐槸Obesrver綾伙紝褰揝ubject綾葷殑鐘舵佸彂鐢熷彉鍖栫殑鏃跺欓氱煡涓庝箣瀵瑰簲鐨凮besrver綾諱滑涔熷幓鐩稿簲鐨勬洿鏂扮姸鎬侊紝鍚屾椂鏀寔鍔ㄦ佺殑娣誨姞鍜屽垹闄bserver瀵硅薄鐨勫姛鑳姐侽besrver妯″紡鐨勫疄鐜拌鐐規(guī)槸錛岀涓涓鑸瑂ubject綾婚兘鏄噰鐢ㄩ摼琛ㄧ瓑瀹瑰櫒鏉ュ瓨鏀綩bserver瀵硅薄錛岀浜屾娊鍙栧嚭Observer瀵硅薄鐨勪竴浜涘叕鍏辯殑灞炴у艦鎴怬bserver鍩虹被錛岃孲ubject涓繚瀛樼殑鍒欐槸Observer綾誨璞$殑鎸囬拡錛岃繖鏍峰氨浣縎ubject鍜屽叿浣撶殑Observer瀹炵幇浜嗚В鑰︼紝涔熷氨鏄疭ubject涓嶉渶瑕佸幓鍏沖績鍒板簳鏄摢涓狾bserver瀵規(guī)斁榪涗簡鑷繁鐨勫鍣ㄤ腑銆傜敓媧諱腑鏈夊緢澶氫緥瀛愬彲浠ョ湅鍋氭槸Observer妯″紡鐨勮繍鐢紝姣旀柟璇達紝涓涓彮鏈変竴涓彮涓諱換錛圫ubject錛夛紝浠栫鐞嗘墜涓嬬殑涓甯鐢燂紙Observer錛夛紝褰撶彮閲屾湁涓浜涗簨鎯呭彂鐢熼渶瑕侀氱煡瀛︾敓鐨勬椂鍊欙紝鐝富浠昏鍋氱殑涓嶆槸閫愪釜瀛︾敓鎸ㄤ釜鐨勯氱煡鑰屾槸鎶婂鐢熷彫闆嗚搗鏉ヤ竴璧烽氱煡錛屽疄鐜頒簡鐝富浠誨拰鍏蜂綋瀛︾敓鐨勫叧緋昏В鑰︺?/p>
瀹炵幇錛?/p>
1錛塐bserver.h
/**//******************************************************************** 銆銆銆 purpose:銆銆銆 Observer妯″紡鐨勬紨紺轟唬鐮?br>*********************************************************************/ #ifndef OBSERVER_H #include <list> typedef int STATE; class Observer; // Subject鎶借薄鍩虹被,鍙渶瑕佺煡閬揙bserver鍩虹被鐨勫0鏄庡氨鍙互浜?br>class Subject 銆銆銆 void Notify();銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆 // 閫氱煡瀵硅薄鏀瑰彉鐘舵?br>銆銆銆 void Attach(Observer *pObserver);銆銆銆銆銆銆銆 // 鏂板瀵硅薄 銆銆銆 // 铏氬嚱鏁?鎻愪緵榛樿鐨勫疄鐜?媧劇敓綾誨彲浠ヨ嚜宸卞疄鐜版潵瑕嗙洊鍩虹被鐨勫疄鐜?br>銆銆銆 virtual void銆銆銆 SetState(STATE nState);銆銆銆 // 璁劇疆鐘舵?br>銆銆銆 virtual STATE銆銆銆 GetState();銆銆銆銆銆銆銆 // 寰楀埌鐘舵?/p>
protected: // Observer鎶借薄鍩虹被 銆銆銆 // 綰櫄鍑芥暟,鍚勪釜媧劇敓綾誨彲鑳芥湁涓嶅悓鐨勫疄鐜?br>銆銆銆 // 閫氱煡Observer鐘舵佸彂鐢熶簡鍙樺寲 protected: // ConcreateSubject綾?媧劇敓鍦⊿ubject綾?br>class ConcreateSubject 銆銆銆 // 媧劇敓綾昏嚜宸卞疄鐜版潵瑕嗙洊鍩虹被鐨勫疄鐜?br>銆銆銆 virtual void銆銆銆 SetState(STATE nState);銆銆銆 // 璁劇疆鐘舵?br>銆銆銆 virtual STATE銆銆銆 GetState();銆銆銆銆銆銆銆 // 寰楀埌鐘舵?/p>
}; // ConcreateObserver綾繪淳鐢熻嚜Observer 銆銆銆 // 铏氬嚱鏁?瀹炵幇鍩虹被鎻愪緵鐨勬帴鍙?br>銆銆銆 virtual void Update(Subject* pSubject); #endif /**//******************************************************************** 銆銆銆 purpose:銆銆銆 Observer妯″紡鐨勬紨紺轟唬鐮?br>*********************************************************************/ #include "Observer.h" /**//* -------------------------------------------------------------------- void Subject::Attach(Observer *pObserver) 銆銆銆 m_ListObserver.push_back(pObserver); void Subject::Detach(Observer *pObserver) 銆銆銆 if (m_ListObserver.end() != iter) 銆銆銆 std::cout << "Detach an Observern"; void Subject::Notify() 銆銆銆 std::list<Observer*>::iterator iter1, iter2; 銆銆銆 for (iter1 = m_ListObserver.begin(), iter2 = m_ListObserver.end(); void Subject::SetState(STATE nState) STATE Subject::GetState() Subject::~Subject() 銆銆銆 for (iter1 = m_ListObserver.begin(), iter2 = m_ListObserver.end(); 銆銆銆 m_ListObserver.clear(); /**//* -------------------------------------------------------------------- STATE ConcreateSubject::GetState() /**//* -------------------------------------------------------------------- 銆銆銆 m_nObserverState = pSubject->GetState(); 銆銆銆 std::cout << "The ObeserverState is " << m_nObserverState << std::endl; /**//******************************************************************** 銆銆銆 purpose:銆銆銆 Observer妯″紡鐨勬祴璇曚唬鐮?br>*********************************************************************/ #include "Observer.h" int main() 銆銆銆 Subject* p = new ConcreateSubject; 銆銆銆 p->Detach(p1); 銆銆銆 delete p; 銆銆銆 system("pause"); 銆銆銆 return 0; 鍦ㄨ澶氬箍娉涘簲鐢ㄧ殑紼嬪簭搴擄紝鎴戜滑浼氱湅鍒扮被浼?#pragma pack(push, 4) 絳夎繖鏍風殑鏍囩ず銆傚洜涓虹敤鎴蜂細浠繪剰鏇存敼浠栦滑鐨勭粨鏋勬垚鍛樺榻愰夐」錛屽浜庡厛浜庤繖浜涘唴瀹瑰垱寤虹殑紼嬪簭搴撴潵璇達紝涓嶈兘紜繚涓瀹氱殑鍐呭瓨甯冨眬灝嗗彲鑳藉湪棰勫厛涔﹀啓鐨勪竴浜涙暟鎹闂ā鍧椾笂瀵艱嚧閿欒錛屾垨鑰呮牴鏈笉鍙兘瀹炵幇銆?br>
涓銆侀夋嫨鍏徃鐨勫艦寮忥細
鏅氱殑鏈夐檺璐d換鍏徃錛屾渶浣庢敞鍐岃祫閲?涓囧厓錛岄渶瑕?涓垨2涓互涓婄殑鑲′笢錛?
浠?6騫?鏈堣搗鏂扮殑鍏徃娉曡瀹氾紝鍏佽1涓偂涓滄敞鍐屾湁闄愯矗浠誨叕鍙革紝榪欑鐗規(guī)畩鐨勬湁闄愯矗浠誨叕鍙稿張縐?#8220;涓浜烘湁闄愬叕鍙?#8221;(浣嗗叕鍙稿悕縐頒腑涓嶄細鏈?#8220;涓浜?#8221;瀛楁牱錛屾墽鐓т笂浼氭敞鏄?#8220;鑷劧浜虹嫭璧?#8221;)錛屾渶浣庢敞鍐岃祫閲?0涓囧厓銆傚鏋滃彧鏈変綘涓涓漢浣滀負鑲′笢錛屽垯閫夋嫨涓浜烘湁闄愬叕鍙革紝鏈浣庢敞鍐岃祫閲?0涓囧厓錛涘鏋滀綘鍜屾湅鍙嬨佸浜哄悎浼欐姇璧勫垱涓氾紝鍙夋嫨鏅氱殑鏈夐檺鍏徃錛屾渶浣庢敞鍐岃祫閲?涓囧厓銆傚緩璁綘鍑嗗濂芥敞鍐岃祫閲?涓囧厓銆?
浜屻佹敞鍐屽叕鍙告墍闇鐨勬敞鍐岃祫鏂欙細
(1)涓漢璧勬枡錛堣韓浠借瘉銆佹硶浜烘埛鍙f湰澶嶅嵃浠舵垨鎴風睄璇佹槑銆佸眳浣忓湴鍧銆佺數璇濆彿鐮侊級
(2)娉ㄥ唽璧勯噾
(3)鎷熻娉ㄥ唽鍏徃鍚嶇О鑻ュ共
(4)鍏徃緇忚惀鑼冨洿
(5)縐熸埧鎴夸駭璇併佺璧佸悎鍚?
(6)鍏徃浣忔墍
(7)鑲′笢鍚嶅唽鍙婅偂涓滆仈緋葷數璇濄佽仈緋誨湴鍧
(8)鍏徃鐨勬満鏋勫強鍏朵駭鐢熷姙娉曘佽亴鏉冦佽浜嬭鍒?
(9)鍏徃绔犵▼
涓夈佹敞鍐屽叕鍙哥殑姝ラ錛?
1.鏍稿悕錛氬埌宸ュ晢灞鍘婚鍙栦竴寮?#8220;浼佷笟(瀛楀彿)鍚嶇О棰勫厛鏍稿噯鐢寵琛?#8221;錛屽~鍐欎綘鍑嗗鍙栫殑鍏徃鍚嶇О錛岀敱宸ュ晢灞涓婂伐鍟嗗眬鍐呴儴緗戞绱㈡槸鍚︽湁閲嶅悕錛屽鏋滄病鏈夐噸鍚嶏紝灝卞彲浠ヤ嬌鐢ㄨ繖涓悕縐幫紝灝變細鏍稿彂涓寮?#8220;浼佷笟(瀛楀彿)鍚嶇О棰勫厛鏍稿噯閫氱煡涔?#8221;銆傚伐鍟嗗悕縐版牳鍑嗚垂鏄?0鍏冿紝浜ょ粰宸ュ晢灞銆?40鍏冨彲浠ュ府浣犳绱?涓悕瀛楋紝寰堝鍚嶅瓧閲嶅錛屾墍浠ヤ竴鑸父瑙佺殑鍚嶅瓧灝變笉鐢ㄨ瘯浜嗭紝鍏嶅緱鑺卞啢鏋夐挶銆?
2.縐熸埧錛?鍘諱笓闂ㄧ殑鍐欏瓧妤肩涓闂村姙鍏錛屽鏋滀綘鑷繁鏈夊巶鎴挎垨鑰呭姙鍏涔熷彲浠ワ紝鏈夌殑鍦版柟涓嶅厑璁稿湪灞呮皯妤奸噷鍔炲叕銆?浣犺浜ゆ埧縐熺粰鎵縐熷姙鍏鐨勬埧涓?鎵鏈夋潈浜?錛屽亣璁懼姙鍏鐨勬埧縐熸槸1000鍏?鏈?涓鑸搗縐熸渶灝?涓湀,6涓湀鐨勬埧縐熸槸6000鍏冦?
3.絳捐縐熸埧鍚堝悓錛氫綘瑕佷笌浣犳墍縐熺殑鍔炲叕瀹ょ殑鎴夸笢絳懼畾縐熸埧鍚堝悓,騫惰鎴夸笢鎻愪緵鎴夸駭璇佺殑澶嶅嵃浠躲傜鎴垮悎鍚屾墦鍗拌垂5浠?5鍏冿紝鎴夸駭璇佸鍗頒歡5寮?.5鍏冦?
4.涔扮鎴跨殑鍗拌姳紼庯細浣犺鍒扮◣鍔″眬鍘諱拱鍗拌姳紼庯紝鎸夊勾縐熼噾鐨勫崈鍒嗕箣涓鐨勭◣鐜囪喘涔幫紝璐村湪鎴跨鍚堝悓鐨勯欏點備緥濡備綘鐨勬瘡騫存埧縐熸槸1.2涓囧厓錛岄偅灝辮涔?2鍏冮挶鐨勫嵃鑺辯◣錛屽悗闈㈠嚒鏄渶瑕佺敤鍒版埧縐熷悎鍚岀殑鍦版柟錛岄兘闇瑕佹槸璐翠簡鍗拌姳紼庣殑鍚堝悓澶嶅嵃浠躲?
5.緙栧啓“鍏徃绔犵▼”錛氬彲浠ュ湪宸ュ晢灞緗戠珯涓嬭澆“鍏徃绔犵▼”鐨勬牱鏈紝淇敼涓涓嬪氨鍙互浜嗐傜珷紼嬬殑鏈鍚庣敱鎵鏈夎偂涓滅鍚嶃?鍋囪绔犵▼鎵撳嵃5浠?鑲′笢2浜哄悇2浠姐佸伐鍟嗗眬1浠姐侀摱琛?浠姐佷細璁″笀浜嬪姟鎵1浠?錛岀珷紼嬫墦鍗拌垂15鍏冦佷笅杞藉叕鍙哥珷紼嬬殑涓婄綉璐?鍏冦?
6.鍒葷绔狅細 鍘昏涓婂埢绔犵殑鍦版柟鍒諱竴涓绔狅紝緇欎粬浠鍒繪硶浜虹绔?鏂瑰艦鐨?銆傚埢绔犺垂鐢?0鍏冦?
7.鍒頒細璁″笀浜嬪姟鎵棰嗗彇“閾惰璇㈠緛鍑?#8221;錛氳仈緋諱竴瀹朵細璁″笀浜嬪姟鎵錛岄鍙栦竴寮?#8220;閾惰璇㈠緛鍑?#8221;錛屽繀欏繪槸鍘熶歡錛屼細璁″笀浜嬪姟鎵鐩栭矞绔犮傚鏋滀綘涓嶆竻妤氾紝鍙互鐪嬫姤綰鎬笂鐨勫垎綾誨箍鍛婏紝鏈夊緢澶氫細璁″笀浜嬪姟鎵鐨勫箍鍛娿傞摱琛岃寰佸嚱10鍏冦?
8.鍘婚摱琛屽紑绔嬪叕鍙擱獙璧勬埛錛?鎵鏈夎偂涓滃甫涓婅嚜宸卞叆鑲$殑閭d竴閮ㄥ垎閽卞埌閾惰錛屽甫涓婂叕鍙哥珷紼嬨佸伐鍟嗗眬鍙戠殑鏍稿悕閫氱煡銆佹硶浜轟唬琛ㄧ殑縐佺珷銆佽韓浠借瘉銆佺敤浜庨獙璧勭殑閽便佺┖鐧借寰佸嚱琛ㄦ牸錛屽埌閾惰鍘誨紑绔嬪叕鍙稿笎鎴鳳紝浣犺鍛婅瘔閾惰鏄紑楠岃祫鎴楓傚紑绔嬪ソ鍏徃甯愭埛鍚庯紝鍚勪釜鑲′笢鎸夎嚜宸卞嚭璧勯鍚戝叕鍙稿笎鎴蜂腑瀛樺叆鐩稿簲鐨勯挶銆?閾惰浼氬彂緇欐瘡涓偂涓滅即嬈懼崟銆佸茍鍦ㄨ寰佸嚱涓婄洊閾惰鐨勭珷銆傚叕鍙擱獙璧勬埛寮鎴瘋垂20鍏冦?
娉ㄦ剰錛氬叕鍙告硶瑙勫畾錛屾敞鍐屽叕鍙告椂錛屾姇璧勪漢(鑲′笢)蹇呴』緙寸撼瓚抽鐨勮祫鏈紝鍙互浠ヨ捶甯佸艦寮?涔熷氨鏄漢姘戝竵)鍑鴻祫錛屼篃鍙互浠ュ疄鐗?濡傛苯杞︺佹埧浜с佺煡璇嗕駭鏉冪瓑)鍑鴻祫銆傚埌閾惰鍔炵殑鍙槸璐у竵鍑鴻祫榪欎竴閮ㄥ垎錛屽鏋滀綘鏈夊疄鐗┿佹埧浜х瓑浣滀負鍑鴻祫鐨勶紝闇瑕佸埌浼氳甯堜簨鍔℃墍閴村畾鍏朵環(huán)鍊煎悗鍐嶄互鍏跺疄闄呬環(huán)鍊煎嚭璧勶紝姣旇緝楹葷儲錛屽洜姝ゅ緩璁綘鐩存帴鎷塊挶鏉ュ嚭璧勶紝鍏徃娉曚笉綆′綘鐢ㄤ粈涔堟墜孌墊嬁鐨勯挶錛岃嚜宸辯殑涔熷ソ銆佸熺殑涔熷ソ錛屽彧瑕佸鏁扮即瓚沖嚭璧勬鍗沖彲銆?
9.鍔炵悊楠岃祫鎶ュ憡錛氭嬁鐫閾惰鍑哄叿鐨勮偂涓滅即嬈懼崟銆侀摱琛岀洊绔犲悗鐨勮寰佸嚱錛屼互鍙婂叕鍙哥珷紼嬨佹牳鍚嶉氱煡銆佹埧縐熷悎鍚屻佹埧浜ц瘉澶嶅嵃浠訛紝鍒頒細璁″笀浜嬪姟鎵鍔炵悊楠岃祫鎶ュ憡錛屼細璁″笀浜嬪姟甯堥獙璧勬姤鍛婃寜娉ㄥ唽璧勬湰鏀惰垂銆?0涓囧厓浠ヤ笅娉ㄥ唽璧勯噾楠岃祫璐?00鍏冦?
10.娉ㄥ唽鍏徃錛氬埌宸ュ晢灞棰嗗彇鍏徃璁劇珛鐧昏鐨勫悇縐嶈〃鏍鹼紝鍖呮嫭璁劇珛鐧昏鐢寵琛ㄣ佽偂涓?鍙戣搗浜?鍚嶅崟銆佽懀浜嬬粡鐞嗙洃鐞嗘儏鍐點佹硶浜轟唬琛ㄧ櫥璁拌〃銆佹寚瀹氫唬琛ㄦ垨濮旀墭浠g悊浜虹櫥璁拌〃銆傛敞鍐岀櫥璁拌垂錛屾寜娉ㄥ唽璧勯噾鐨勪竾鍒嗕箣8鏀跺彇銆傚~濂藉悗錛岃繛鍚屾牳鍚嶉氱煡銆佸叕鍙哥珷紼嬨佹埧縐熷悎鍚屻佹埧浜ц瘉澶嶅嵃浠躲侀獙璧勬姤鍛婁竴璧蜂氦緇欏伐鍟嗗眬銆傚ぇ姒?涓伐浣滄棩鍚庡彲棰嗗彇鎵х収銆傛敞鍐屽叕鍙告墜緇垂300鍏冦?
11.鍑惀涓氭墽鐓э紝鍒板叕瀹夊眬鐗硅縐戞寚瀹氱殑鍒葷珷紺撅紝鍘誨埢鍏珷銆佽儲鍔$珷銆傚悗闈㈡楠や腑錛屽潎闇瑕佺敤鍒板叕绔犳垨璐㈠姟绔犮傚叕绔?0鍏冿紝璐㈠姟绔?0鍏冦?
12.鍔炵悊浼佷笟緇勭粐鏈烘瀯浠g爜璇侊細鍑惀涓氭墽鐓у埌鎶鏈洃鐫e眬鍔炵悊緇勭粐鏈烘瀯浠g爜璇侊紝璐圭敤鏄?0鍏冦傚姙榪欎釜璇侀渶瑕佸崐涓湀錛屾妧鏈洃鐫e眬浼氶鍏堝彂涓涓鍏堝彈鐞嗕唬鐮佽瘉鏄庢枃浠訛紝鍑繖涓枃浠跺氨鍙互鍔炵悊鍚庨潰鐨勭◣鍔$櫥璁拌瘉銆侀摱琛屽熀鏈埛寮鎴鋒墜緇簡銆?
13.鍘婚摱琛屽紑鍩烘湰鎴鳳細鍑惀涓氭墽鐓с佺粍緇囨満鏋勪唬鐮佽瘉錛屽幓閾惰寮绔嬪熀鏈笎鍙楓傛渶濂芥槸鍦ㄥ師鏉ュ姙鐞嗛獙璧勬椂鐨勯偅涓摱琛岀殑鍚屼竴緗戠偣鍘誨姙鐞嗭紝鍚﹀垯錛屼細澶氭敹100鍏冪殑楠岃祫甯愭埛璐圭敤銆?寮鍩烘湰鎴烽渶瑕佸~寰堝琛紝浣犳渶濂芥妸鑳藉甫榻愮殑涓滆タ鍏ㄩ儴甯︿笂錛岃涓嶇劧瑕佽窇寰堝瓚燂紝鍖呮嫭钀ヤ笟鎵х収姝f湰鍘熶歡銆佽韓浠借瘉銆佺粍緇囨満鏋勪唬鐮佽瘉銆佸叕璐㈢珷銆佹硶浜虹珷銆?
寮鍩烘湰鎴鋒椂錛岃繕闇瑕佽喘涔頒竴涓瘑鐮佸櫒(浠?005騫翠笅鍗婂勾璧鳳紝澶у閾惰閮芥湁榪欎釜瑙勫畾)錛屼粖鍚庝綘鐨勫叕鍙稿紑鏀エ銆佸垝嬈炬椂錛岄兘闇瑕佷嬌鐢ㄥ瘑鐮佸櫒鏉ョ敓鎴愬瘑鐮併傚叕鍙稿熀鏈笎鍙峰紑鎴瘋垂20鍏冿紝瀵嗙爜鍣?80鍏冦?
14.鍔炵悊紼庡姟鐧昏錛氶鍙栨墽鐓у悗錛?0鏃ュ唴鍒板綋鍦扮◣鍔″眬鐢寵棰嗗彇紼庡姟鐧昏璇併備竴鑸殑鍏徃閮介渶瑕佸姙鐞?縐嶇◣鍔$櫥璁拌瘉錛屽嵆鍥界◣鍜屽湴紼庛傝垂鐢ㄦ槸鍚?0鍏冿紝鍏?0鍏冦?
15.璇峰吋鑱屼細璁★細鍔炵悊紼庡姟鐧昏璇佹椂錛屽繀欏繪湁涓涓細璁★紝鍥犱負紼庡姟灞瑕佹眰鎻愪氦鐨勮祫鏂欏叾涓湁涓欏規(guī)槸浼氳璧勬牸璇佸拰韜喚璇併備綘鍙厛璇蜂竴涓吋鑱屼細璁★紝灝忓叕鍙稿垰寮濮嬭鐨勫吋鑱屼細璁′竴鑸?00鍏冨伐璧勫氨鍙互浜嗐?
16.鐢寵棰嗚喘鍙戠エ錛氬鏋滀綘鐨勫叕鍙告槸閿鍞晢鍝佺殑錛屽簲璇ュ埌鍥界◣鍘葷敵璇峰彂紲紝濡傛灉鏄湇鍔℃ц川鐨勫叕鍙革紝鍒欏埌鍦扮◣鐢抽鍙戠エ銆?寮濮嬪彲鍏堥璐?00鍏冪殑鍙戠エ銆?
鏈鍚庡氨寮濮嬭惀涓氫簡銆?
鍥涖佹敞鍐屽叕鍙哥殑璐圭敤錛?
1銆佸伐鍟嗗眬宸ュ晢鍚嶇О鏍稿噯錛?0鍏?
2銆佸叕鍙稿姙鍏鎴跨6涓湀錛?000鍏?
3銆佺鎴垮悎鍚屾墦鍗拌垂5浠?5鍏冿紝鎴夸駭璇佸鍗頒歡5寮?.5鍏?
4銆佺鎴跨殑鍗拌姳紼?2鍏?
5銆佷笅杞藉叕鍙哥珷紼嬬殑涓婄綉璐?鍏冿紝鍏徃绔犵▼鎵撳嵃璐?5鍏?
6銆佸埢娉曚漢縐佺珷20鍏?
7銆佷細璁″笀浜嬪姟鎵鐨勯摱琛岃寰佸嚱10鍏?
8銆侀摱琛屽紑绔嬪叕鍙擱獙璧勬埛寮鎴瘋垂20鍏?
9銆佷細璁″笀浜嬪姟鎵鍔炵悊楠岃祫鎶ュ憡500鍏?
10銆佸伐鍟嗗眬娉ㄥ唽鍏徃鎵嬬畫璐?00鍏冿紝淇℃伅鍗?20鍏?
11銆佸叕绔?涓?20鍏冿紝璐㈠姟绔?涓?0鍏?
12銆佹妧鏈洃鐫e眬鍔炵悊緇勭粐鏈烘瀯浠g爜璇?48鍏?
13銆侀摱琛屽紑绔嬪叕鍙稿熀鏈笎鍙峰紑鎴瘋垂20鍏冦佸瘑鐮佸櫒280鍏?
14銆佸浗紼庣◣鍔$櫥璁拌瘉60鍏冿紝鍦扮◣紼庡姟鐧昏璇?0鍏?
15銆佸吋鑱屼細璁″伐璧勶紝200鍏?
16銆佺敵璇烽璐彂紲紝500鍏?
鍚堣錛?502.5鍏?
濡傛灉涓嶇畻鎴跨銆佷細璁″伐璧勩佸彂紲紝鍒欏悎璁?802.5鍏冦?
娉ㄥ唽璧勬湰鏈灝?涓囧厓銆?
娉ㄥ唽鐧昏璐規(guī)寜娉ㄥ唽璧勬湰鐨?.08%(1000涓囦互鍐?,0.04%(1000涓囦互涓婄殑瓚呰繃閮ㄥ垎)鏀跺彇
钀ヤ笟紼庯細閿鍞晢鍝佺殑鍏徃錛屾寜鎵寮鍙戠エ棰濈殑4%寰佹敹澧炴畺紼庯紱鎻愪緵鏈嶅姟鐨勫叕鍙革紝鎸夋墍寮鍙戠エ棰濈殑5%寰佹敹钀ヤ笟紼庛?
鎵寰楃◣錛氬浼佷笟鐨勭函鍒╂鼎寰佹敹18-33%鐨勪紒涓氭墍寰楃◣銆?
鍒╂鼎鏀跺叆鍦?涓囧厓錛堝惈3涓囧厓錛変互涓嬬殑紼庣巼涓?8%錛屽埄娑︽敹鍏ュ湪3涓囧厓浠ヤ笂10涓囧厓錛堝惈10涓囧厓錛夌殑紼庣巼涓?7%錛?0涓囧厓浠ヤ笂鐨勪負33%銆?
浜斻佹敞鍐屽叕鍙哥殑鐩稿叧璇存槑錛?
1.娉ㄥ唽鍏徃浼氫笉鍒板崐騫存椂闂達紝鏈蹇渶瑕?0澶╂椂闂淬傚湴鍖轟笉鍚屾敞鍐屽叕鍙哥殑璐圭敤涔熸湁鎵涓嶅悓銆?
2.瑕佹敞鍐屼竴涓叕鍙革紝棣栧厛鎯沖ソ緇忚惀浠涔堬紝鎬庢牱緇忚惀濂斤紝鍐嶆潵娉ㄥ唽銆傝涓嶏紝娉ㄥ唽浜嗕篃娌℃湁鐢紝娉ㄥ唽浜嗗叕鍙告槸闇瑕佸緢澶氭垚鏈殑錛屼笉鏄竴浠?#8220;濂界帺”鐨勪簨鎯呫?
3.娉ㄥ唽涓綋綆鍗曟槗鍔烇紱鑰屾敞鍐屽叕鍙歌鏈夌珷紼嬨佸悎鍚岋紝瑕侀獙璧勶紝紼嬪簭鎸哄鐨勩?鍦ㄦ姇鍏ヤ笉鏄お澶氭椂錛岃繕鏄敞鍐屼釜浣撲負濂姐?
4.鍓嶆湡鍙鎬у垎鏋愯皟鏌ワ紝寤鴻浣犺嚜宸辮鐪熺殑鑰冭檻涓涓?
5.鍏徃蹇呴』寤虹珛鍋ュ叏鐨勪細璁″埗搴︼紝浣犲彲鑳芥媴蹇冭嚜宸變笉浼氾紝鎬庝箞鍔烇紵鍒氬紑濮嬫垚绔嬬殑鍏徃錛屼笟鍔″皯錛屽浼氳鐨勫伐浣滈噺涔熼潪甯稿皬錛屼綘鍙互璇蜂竴涓吋鑱屼細璁★紝姣忎釜鏈堝埌浣犵殑鍏徃甯綘寤哄笎錛屼簩銆佷笁澶╂椂闂村氨澶熶簡錛岀粰浠?00-500宸﹀彸鐨勫伐璧勫嵆鍙?
6.姣忎釜鏈?鏃?10鏃ユ寜鏃跺悜紼庡姟鐢蟲姤紼庯紝鍗充嬌娌℃湁寮灞曚笟鍔′笉闇瑕佺即紼庯紝涔熻榪涜闆剁敵鎶ワ紝鍚﹀垯浼氳緗氭鐨勩傜綒嬈鵑搴﹁秴榪囦竴澶?00鍏冦傝惀涓氭墽鐓у姙鐞嗕笅鏉ュ悗涓涓湀鍐呭繀欏誨姙鐞嗙◣鍔$櫥璁般傛瘡騫?-6鏈堝勾瀹氭椂騫存钀ヤ笟鎵х収銆?
7.瀵逛紒涓氭墍寰楃◣錛屽仛甯愬緢鍏抽敭錛屽鏋滃笎闈笂浣犵殑鍒╂鼎寰堝錛岄偅紼庣巼灝遍珮銆傛墍浠ワ紝騫沖父鐨勮喘涔拌澶囬兘瑕佸紑鍙戠エ錛屼綘鍚冮キ銆佸潗杞︾殑紲ㄩ兘鐣欒搗鏉ワ紝鍙互鍋氫負浣犵殑浼佷笟榪愪綔鎴愭湰銆?
8.钀ヤ笟紼庢槸瀵硅惀涓氶寰佺◣錛屼笉綆′綘璧氭病鏈夎禋閽憋紝鍙湁鍙戠敓浜嗕氦鏄擄紝寮浜嗗彂紲紝灝辮寰佺◣錛涙墍寰楃◣錛屾槸瀵瑰埄娑﹀緛紼庯紝鍒╂鼎灝辨槸钀ヤ笟棰濇墸鍑忓悇縐嶆垚鏈悗鍓╀綑鐨勯挶錛屽彧鏈夎禋浜嗛挶錛屾墠浼氬緛鎵寰楃◣銆?
9.鏈夐檺璐d換鍏徃鍙互娉ㄥ唽鍒嗗叕鍙搞?
10.寮鍔炶垂鏄寚浼佷笟鍦ㄧ寤烘湡闂村彂鐢熺殑璐圭敤錛屽寘鎷寤烘湡浜哄憳宸ヨ祫銆佸姙鍏垂銆佸煿璁垂銆佸樊鏃呰垂銆佸嵃鍒瘋垂銆佹敞鍐岀櫥璁拌垂浠ュ強涓嶈鍏ュ浐瀹氳祫浜у拰鏃犲艦璧勪駭璐緩鎴愭湰鐨勬眹鍏戞崯鐩婂拰鍒╂伅鏀嚭銆傜寤烘湡鏄寚浼佷笟琚壒鍑嗙寤轟箣鏃ヨ搗鑷沖紑濮嬬敓浜с佺粡钀ワ紙鍖呮嫭璇曠敓浜с佽瘯钀ヤ笟錛変箣鏃ョ殑鏈熼棿銆?
濡傛灉c++綾葷殑鏋勯犲嚱鏁版湁涓涓弬鏁幫紝閭d箞鍦ㄧ紪璇戠殑鏃跺欏氨浼氭湁涓涓己鐪佺殑杞崲鎿嶄綔錛氬皢璇ユ瀯閫犲嚱鏁板搴旀暟鎹被鍨嬬殑鏁版嵁杞崲涓鴻綾誨璞★紝濡備笅闈㈡墍紺猴細
class MyClass
{
public:
MyClass( int num );
}
....
MyClass obj = 10; //ok,convert int to MyClass
鍦ㄤ笂闈㈢殑浠g爜涓紪璇戝櫒鑷姩灝嗘暣鍨嬭漿鎹負MyClass綾誨璞★紝瀹為檯涓婄瓑鍚屼簬涓嬮潰鐨勬搷浣滐細
MyClass temp(10);
MyClass obj = temp;
涓婇潰鐨勬墍鏈夌殑鎿嶄綔鍗蟲槸鎵璋撶殑"闅愬紡杞崲"銆?br>
濡傛灉瑕侀伩鍏嶈繖縐嶈嚜鍔ㄨ漿鎹㈢殑鍔熻兘錛屾垜浠鎬庝箞鍋氬憿錛熷樋鍢胯繖灝辨槸鍏抽敭瀛梕xplicit鐨勪綔鐢ㄤ簡錛屽皢綾葷殑鏋勯犲嚱鏁板0鏄庝負"鏄劇ず"錛屼篃灝辨槸鍦ㄥ0鏄庢瀯閫犲嚱鏁扮殑鏃跺欏墠闈㈡坊鍔犱笂explicit鍗沖彲錛岃繖鏍峰氨鍙互闃叉榪欑鑷姩鐨勮漿鎹㈡搷浣滐紝濡傛灉鎴戜滑淇敼涓婇潰鐨凪yClass綾葷殑鏋勯犲嚱鏁頒負鏄劇ず鐨勶紝閭d箞涓嬮潰鐨勪唬鐮佸氨涓嶈兘澶熺紪璇戦氳繃浜嗭紝濡備笅鎵紺猴細
class MyClass
{
public:
explicit MyClass( int num );
}
....
MyClass obj = 10; //err,can't non-explict convert
class isbn_mismatch:public std::logic_error{
public:
explicit isbn_missmatch(const std::string &s):std:logic_error(s){}
isbn_mismatch(const std::string &s,const std::string &lhs,const std::string &rhs):
std::logic_error(s),left(lhs),right(rhs){}
const std::string left,right;
virtual ~isbn_mismatch() throw(){}
};
Sales_item& operator+(const Sales_item &lhs,const Sales_item rhs)
{
if(!lhs.same_isbn(rhs))
throw isbn_mismatch("isbn missmatch",lhs.book(),rhs.book());
Sales_item ret(lhs);
ret+rhs;
return ret;
}
Sales_item item1,item2,sum;
while(cin>>item1>>item2)
{
try{
sun=item1+item2;
}catch(const isbn_mismatch &e)
{
cerr<<e.what()<<"left isbn is:"<<e.left<<"right isbn is:"<<e.right<<endl;
}
}
鐢ㄤ簬鐢ㄦ埛鑷畾涔夌被鍨嬬殑鏋勯犲嚱鏁?鎸囧畾瀹冩槸榛樿鐨勬瀯閫犲嚱鏁?涓嶅彲鐢ㄤ簬杞崲鏋勯犲嚱鏁?鍥犱負鏋勯犲嚱鏁版湁涓夌:1鎷瘋礉鏋勯犲嚱鏁?杞崲鏋勯犲嚱鏁?涓鑸殑鏋勯犲嚱鏁?鎴戣嚜宸辯殑鏈^_^)
鍙?濡傛灉涓涓被鎴栫粨鏋勫瓨鍦ㄥ涓瀯閫犲嚱鏁版椂,explicit 淇グ鐨勯偅涓瀯閫犲嚱鏁板氨鏄粯璁ょ殑
class isbn_mismatch:public std::logic_error{
public:
explicit isbn_missmatch(const std::string &s):std:logic_error(s){}
isbn_mismatch(const std::string &s,const std::string &lhs,const std::string &rhs):
std::logic_error(s),left(lhs),right(rhs){}
const std::string left,right;
virtual ~isbn_mismatch() throw(){}
};
Sales_item& operator+(const Sales_item &lhs,const Sales_item rhs)
{
if(!lhs.same_isbn(rhs))
throw isbn_mismatch("isbn missmatch",lhs.book(),rhs.book());
Sales_item ret(lhs);
ret+rhs;
return ret;
}
Sales_item item1,item2,sum;
while(cin>>item1>>item2)
{
try{
sun=item1+item2;
}catch(const isbn_mismatch &e)
{
cerr<<e.what()<<"left isbn is:"<<e.left<<"right isbn is:"<<e.right<<endl;
}
}
榪欎釜 銆夾NSI/ISO C++ Professional Programmer's Handbook 銆嬫槸榪欐牱璇寸殑
explicit Constructors
A constructor that takes a single argument is, by default, an implicit conversion operator, which converts its argument to
an object of its class (see also Chapter 3, "Operator Overloading"). Examine the following concrete example:
class string
{
private:
int size;
int capacity;
char *buff;
public:
string();
string(int size); // constructor and implicit conversion operator
string(const char *); // constructor and implicit conversion operator
~string();
};
Class string has three constructors: a default constructor, a constructor that takes int, and a constructor that
constructs a string from const char *. The second constructor is used to create an empty string object with an
initial preallocated buffer at the specified size. However, in the case of class string, the automatic conversion is
dubious. Converting an int into a string object doesn't make sense, although this is exactly what this constructor does.
Consider the following:
int main()
{
string s = "hello"; //OK, convert a C-string into a string object
int ns = 0;
s = 1; // 1 oops, programmer intended to write ns = 1,
}
In the expression s= 1;, the programmer simply mistyped the name of the variable ns, typing s instead. Normally,
the compiler detects the incompatible types and issues an error message. However, before ruling it out, the compiler first
searches for a user-defined conversion that allows this expression; indeed, it finds the constructor that takes int.
Consequently, the compiler interprets the expression s= 1; as if the programmer had written
s = string(1);
You might encounter a similar problem when calling a function that takes a string argument. The following example
can either be a cryptic coding style or simply a programmer's typographical error. However, due to the implicit
conversion constructor of class string, it will pass unnoticed:
int f(string s);
int main()
{
f(1); // without a an explicit constructor,
//this call is expanded into: f ( string(1) );
//was that intentional or merely a programmer's typo?
}
'In order to avoid such implicit conversions, a constructor that takes one argument needs to be declared explicit:
class string
{
//...
public:
explicit string(int size); // block implicit conversion
string(const char *); //implicit conversion
~string();
};
An explicit constructor does not behave as an implicit conversion operator, which enables the compiler to catch the
typographical error this time:
int main()
{
string s = "hello"; //OK, convert a C-string into a string object
int ns = 0;
s = 1; // compile time error ; this time the compiler catches the typo
}
Why aren't all constructors automatically declared explicit? Under some conditions, the automatic type conversion is
useful and well behaved. A good example of this is the third constructor of string:
string(const char *);
The implicit type conversion of const char * to a string object enables its users to write the following:
string s;
s = "Hello";
The compiler implicitly transforms this into
string s;
//pseudo C++ code:
s = string ("Hello"); //create a temporary and assign it to s
On the other hand, if you declare this constructor explicit, you have to use explicit type conversion:
class string
{
//...
public:
explicit string(const char *);
};
int main()
{
string s;
s = string("Hello"); //explicit conversion now required
return 0;
}
Extensive amounts of legacy C++ code rely on the implicit conversion of constructors. The C++ Standardization
committee was aware of that. In order to not make existing code break, the implicit conversion was retained. However, a
new keyword, explicit, was introduced to the languageto enable the programmer to block the implicit conversion
when it is undesirable. As a rule, a constructor that can be invoked with a single argument needs to be declared
explicit. When the implicit type conversion is intentional and well behaved, the constructor can be used as an
implicit conversion operator.
緗戜笂鎵劇殑璁茬殑鏈濂界殑璐達細
C++ 涓?explicit 鍏抽敭瀛楃殑浣滅敤
鍦?C++ 涓紝 濡傛灉涓涓被鏈夊彧鏈変竴涓弬鏁扮殑鏋勯犲嚱鏁幫紝C++ 鍏佽涓縐嶇壒孌婄殑澹版槑綾誨彉閲忕殑鏂瑰紡銆傚湪榪欑鎯呭喌涓嬶紝鍙互鐩存帴灝嗕竴涓搴斾簬鏋勯犲嚱鏁板弬鏁扮被鍨嬬殑鏁版嵁鐩存帴璧嬪肩粰綾誨彉閲忥紝緙栬瘧鍣ㄥ湪緙栬瘧鏃朵細鑷姩榪涜綾誨瀷杞崲錛屽皢瀵瑰簲浜庢瀯閫犲嚱鏁板弬鏁扮被鍨嬬殑鏁版嵁杞崲涓虹被鐨勫璞°?濡傛灉鍦ㄦ瀯閫犲嚱鏁板墠鍔犱笂 explicit 淇グ璇嶏紝 鍒欎細紱佹榪欑鑷姩杞崲錛屽湪榪欑鎯呭喌涓嬶紝鍗充嬌灝嗗搴斾簬鏋勯犲嚱鏁板弬鏁扮被鍨嬬殑鏁版嵁鐩存帴璧嬪肩粰綾誨彉閲忥紝緙栬瘧鍣ㄤ篃浼氭姤閿欍?br>
涓嬮潰浠ュ叿浣撳疄渚嬫潵璇存槑銆?br>
寤虹珛people.cpp 鏂囦歡錛岀劧鍚庤緭鍏ヤ笅鍒楀唴瀹癸細
class People
{
public:
int age;
explicit People (int a)
{
age=a;
}
};
void foo ( void )
{
People p1(10); //鏂瑰紡涓
People* p_p2=new People(10); //鏂瑰紡浜?br> People p3=10; //鏂瑰紡涓?br>}
榪欐 C++ 紼嬪簭瀹氫箟浜嗕竴涓被 people 錛屽寘鍚竴涓瀯閫犲嚱鏁幫紝 榪欎釜鏋勯犲嚱鏁板彧鍖呭惈涓涓暣褰㈠弬鏁?a 錛屽彲鐢ㄤ簬鍦ㄦ瀯閫犵被鏃跺垵濮嬪寲 age 鍙橀噺銆?br>
鐒跺悗瀹氫箟浜嗕竴涓嚱鏁癴oo錛屽湪榪欎釜鍑芥暟涓垜浠敤涓夌鏂瑰紡鍒嗗埆鍒涘緩浜嗕笁涓?0宀佺殑“浜?#8221;銆傜涓縐嶆槸鏈涓鑸殑綾誨彉閲忓0鏄庢柟寮忋傜浜岀鏂瑰紡鍏跺疄鏄0鏄庝簡涓涓猵eople綾葷殑鎸囬拡鍙橀噺錛岀劧鍚庡湪鍫嗕腑鍔ㄦ佸垱寤轟簡涓涓猵eople瀹炰緥錛屽茍鎶婅繖涓疄渚嬬殑鍦板潃璧嬪肩粰浜唒_p2銆傜涓夌鏂瑰紡灝辨槸鎴戜滑鎵璇寸殑鐗規(guī)畩鏂瑰紡錛屼負浠涔堣鐗規(guī)畩鍛紵鎴戜滑閮界煡閬擄紝C/C++鏄竴縐嶅己綾誨瀷璇█錛屼笉鍚岀殑鏁版嵁綾誨瀷鏄笉鑳介殢鎰忚漿鎹㈢殑錛屽鏋滆榪涜綾誨瀷杞崲錛屽繀欏昏繘琛屾樉寮忓己鍒剁被鍨嬭漿鎹紝鑰岃繖閲岋紝娌℃湁榪涜浠諱綍鏄懼紡鐨勮漿鎹紝鐩存帴灝嗕竴涓暣鍨嬫暟鎹祴鍊肩粰浜嗙被鍙橀噺p3銆?br>
鍥犳錛屽彲浠ヨ錛岃繖閲岃繘琛屼簡涓嬈¢殣寮忕被鍨嬭漿鎹紝緙栬瘧鍣ㄨ嚜鍔ㄥ皢瀵瑰簲浜庢瀯閫犲嚱鏁板弬鏁扮被鍨嬬殑鏁版嵁杞崲涓轟簡璇ョ被鐨勫璞★紝鍥犳鏂瑰紡涓夌粡緙栬瘧鍣ㄨ嚜鍔ㄨ漿鎹㈠悗鍜屾柟寮忎竴鏈緇堢殑瀹炵幇鏂瑰紡鏄竴鏍風殑銆?br>
涓嶇浉淇★紵 鑰沖惉涓鴻櫄錛岀溂瑙佷負瀹烇紝璁╂垜浠湅鐪嬪簳灞傜殑瀹炵幇鏂瑰紡銆?br>
涓轟簡鏇村鏄撴瘮杈冩柟寮忎竴鍜屾柟寮忎笁鐨勫疄鐜版柟寮忥紝鎴戜滑瀵逛笂闈㈢殑浠g爜浣滀竴鐐逛慨鏀癸紝鍘婚櫎鏂瑰紡浜岋細
void foo ( void )
{
People p1(10); //鏂瑰紡涓
People p3=10; //鏂瑰紡涓?br>}
鍘婚櫎鏂瑰紡浜岀殑鍘熷洜鏄柟寮忎簩鏄湪鍫嗕笂鍔ㄦ佸垱寤虹被瀹炰緥錛屽洜姝や細鏈変竴浜涢澶栦唬鐮佸獎鍝嶅垎鏋愩備慨鏀瑰畬鎴愬悗錛岀敤涓嬪垪鍛戒護緙栬瘧 people.cpp
$ gcc -S people.cpp
"-S"閫夐」鏄疓CC杈撳嚭姹囩紪浠g爜銆傚懡浠ゆ墽琛屽悗錛岄粯璁ょ敓鎴恜eople.s銆?鍏抽敭閮ㄥ垎鍐呭濡備笅錛?br>
.globl _Z3foov
.type _Z3foov, @function
_Z3foov:
.LFB5:
pushl %ebp
.LCFI2:
movl %esp, %ebp
.LCFI3:
subl $24, %esp
.LCFI4:
movl $10, 4(%esp)
leal -4(%ebp), %eax
movl %eax, (%esp)
call _ZN6PeopleC1Ei
movl $10, 4(%esp)
leal -8(%ebp), %eax
movl %eax, (%esp)
call _ZN6PeopleC1Ei
leave
ret
鐪?#8220;.LCFI4” 琛屽悗闈㈢殑涓滆タ錛?-4琛屽拰5-8琛屽嚑涔庝竴妯′竴鏍鳳紝1-4琛屽嵆涓烘柟寮忎竴鐨勬眹緙栦唬鐮侊紝5-8鍗充負鏂瑰紡涓夌殑姹囩紪浠g爜銆?緇嗗績鐨勪綘鍙兘鍙戠幇2鍜?琛屾湁鎵涓嶅悓錛屼竴涓槸 -4(%ebp) 鑰屽彟涓涓竴涓槸 -8(%ebp) 錛岃繖鍒嗗埆涓虹被鍙橀噺P1鍜孭3鐨勫湴鍧銆?br>
瀵逛簬涓嶅彲闅忔剰榪涜綾誨瀷杞崲鐨勫己綾誨瀷璇█C/C++鏉ヨ, 榪欏彲浠ヨ鏄疌++鐨勪竴涓壒鎬с傚摝錛屼粖澶╁ソ鍍忎笉鏄璇碈++鐨勭壒鎬э紝鑰屾槸瑕佺煡閬揺xplicit鍏抽敭瀛楃殑浣滅敤錛?br>
explicit鍏抽敭瀛楀埌搴曟槸浠涔堜綔鐢ㄥ憿錛?瀹冪殑浣滅敤灝辨槸紱佹榪欎釜鐗規(guī)с傚鏂囩珷涓寮濮嬭岃█錛屽嚒鏄敤explicit鍏抽敭瀛椾慨楗扮殑鏋勯犲嚱鏁幫紝緙栬瘧鏃跺氨涓嶄細榪涜鑷姩杞崲錛岃屼細鎶ラ敊銆?br>
璁╂垜浠湅鐪嬪惂錛?淇敼浠g爜錛?br>
class People
{
public:
int age;
explicit People (int a)
{
age=a;
}
};
鐒跺悗鍐嶇紪璇戯細
$ gcc -S people.cpp
緙栬瘧鍣ㄧ珛椹姤閿欙細
people.cpp: In function ‘void foo()’:
people.cpp:23: 閿欒錛氳姹備粠 ‘int’ 杞崲鍒伴潪鏍囬噺綾誨瀷 ‘People’
瑙傚療鑰呮ā寮忔妸鐩爣瀵硅瀵熻呯殑渚濊禆榪涜鎶借薄錛氫嬌鐩爣鍙煡閬撹嚜宸辨湁鑻ュ共瑙傚療鑰咃紝浣嗕笉鐭ラ亾榪欎簺瑙傚療鑰呭叿浣撴槸璋侊紝鍙兘鏈夊灝戜釜錛涘綋鐩爣鐘舵佹敼鍙樻椂鍙緇欒繖浜涜瀵熻呬竴涓氱煡錛屼笉蹇呬綔鏇村鐨勪簨鎯呫傝繖鏍風洰鏍囧瑙傚療鑰呯殑渚濊禆灝辮揪鍒頒簡鎶借薄鍜屾渶灝忥紝鑰岀洰鏍囧鍏蜂綋瑙傚療鑰呯殑渚濊禆琚В闄や簡銆?br>
綾誨浘濡備笅錛?br>
Subject 瀵硅薄淇濆瓨涓涓狾bserver寮曠敤鐨勫垪琛紝褰撴垜浠涓涓狢oncreteObserver瀵硅薄瑙傚療Subject瀵硅薄鏃訛紝璋冪敤鍚庤呯殑Attach()鏂規(guī)硶錛屽皢鍓嶈呯殑寮曠敤鍔犲叆璇ュ垪琛ㄤ腑銆傚綋Subject瀵硅薄鐘舵佹敼鍙樻椂錛屽畠璋冪敤鑷韓鐨凬otify鏂規(guī)硶錛岃鏂規(guī)硶璋冪敤鍒楄〃涓瘡涓涓狾bserver鐨?Update()鏂規(guī)硶銆備竴涓狢oncreteObserver鍙閲嶅畾涔塙pdate()灝辮兘鏀跺埌閫氱煡錛屼綔涓哄閫氱煡鐨勫搷搴旓紝Update()璋冪敤 Subject瀵硅薄鐨刧etStatus()鑾峰彇鏁版嵁錛岀劧鍚庢洿鏂拌嚜韜傚綋涓嶉渶瑕佺戶緇瀵熸椂錛孋oncreteObserver瀵硅薄璋冪敤Subject瀵硅薄鐨凞etach()鏂規(guī)硶錛屽叾寮曠敤琚粠鍒楄〃涓Щ闄ゃ?br>
瑙i櫎鐩爣瀵瑰叿浣撹瀵熻呯殑渚濊禆浠ュ悗錛屽緢瀹規(guī)槗澧炲姞鏂扮殑鍏蜂綋瑙傚療鑰咃紝鍥犱負涓嶅彈渚濊禆鐨勬柟闈㈠氨鍙互鑷敱鍙樺寲錛涜岀洰鏍囦篃鍙互鐙珛鍦板鐢紝鍥犱負鏃犳墍渚濊禆鐨勬柟闈㈠氨鍙互涓嶅彈褰卞搷銆?br>
浠ヤ笂涓昏鑰冭檻浜嗕竴涓洰鏍囨湁澶氫釜瑙傚療鑰呯殑鎯呭喌錛屾垜浠娉曡В闄や簡鐩爣瀵瑰叿浣撹瀵熻呯殑渚濊禆錛屼嬌鍏蜂綋瑙傚療鑰呯殑縐嶇被鍜屾暟鐩鏄撴敼鍙樸傛湁鏃跺欎竴涓瀵熻呰瀵熷涓洰鏍囦篃鏄湁鎰忎箟鐨勶紝鍦ㄥ墠闈㈢殑綾誨浘涓紝瑙傚療鑰呭鍏蜂綋鐩爣鐨勪緷璧栦粛鐒跺瓨鍦紝鍥犳鏃犳硶閫傚簲鐩爣鏂歸潰鐨勫彉鍖栥傛庢牱鎶借薄榪欑渚濊禆鍛紵浣胯瀵熻呭彧鐭ラ亾鑻ュ共涓洰鏍囦細鍚戣嚜宸卞彂鍑洪氱煡錛岃屼笉鐭ラ亾榪欎簺鐩爣鍏蜂綋鏄皝錛屽彲鑳芥湁澶氬皯涓紱鍦ㄧ洰鏍囧悜瑙傚療鑰呭彂閫侀氱煡鏃訛紝灝嗕竴涓嚜韜殑寮曠敤浣滀負鍙傛暟錛岀劧鍚庤瀵熻呰皟鐢ㄥ叾鎶借薄鏂規(guī)硶灝卞彲浠ヨ幏寰楃洰鏍囩姸鎬併傝繖灝變嬌寰楄瀵熻呭鐩爣鐨勪緷璧栨槸鎶借薄鐨勶紝瑙傚療鑰呭鍏蜂綋鐩爣鐨勪緷璧栬瑙i櫎浜嗐?br>
綾誨浘濡備笅錛?br>
鍙傝冭祫鏂欙細
1.銆婅璁℃ā寮?鍙鐢ㄩ潰鍚戝璞¤蔣浠剁殑鍩虹銆?Erich Gamma絳夎憲錛屾潕鑻卞啗絳夎瘧 鏈烘宸ヤ笟鍑虹増紺?
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#define SystemBasicInformation 0
#define SystemPerformanceInformation 2
#define SystemTimeInformation 3
#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 (double)((x).LowPart))
typedef struct
{
DWORD dwUnknown1;
ULONG uKeMaximumIncrement;
ULONG uPageSize;
ULONG uMmNumberOfPhysicalPages;
ULONG uMmLowestPhysicalPage;
ULONG uMmHighestPhysicalPage;
ULONG uAllocationGranularity;
PVOID pLowestUserAddress;
PVOID pMmHighestUserAddress;
ULONG uKeActiveProcessors;
BYTE bKeNumberProcessors;
BYTE bUnknown2;
WORD wUnknown3;
} SYSTEM_BASIC_INFORMATION;
typedef struct
{
LARGE_INTEGER liIdleTime;
DWORD dwSpare[76];
} SYSTEM_PERFORMANCE_INFORMATION;
typedef struct
{
LARGE_INTEGER liKeBootTime;
LARGE_INTEGER liKeSystemTime;
LARGE_INTEGER liExpTimeZoneBias;
ULONG uCurrentTimeZoneId;
DWORD dwReserved;
} SYSTEM_TIME_INFORMATION;
// ntdll!NtQuerySystemInformation (NT specific!)
//
// The function copies the system information of the
// specified type into a buffer
//
// NTSYSAPI
// NTSTATUS
// NTAPI
// NtQuerySystemInformation(
// IN UINT SystemInformationClass, // information type
// OUT PVOID SystemInformation, // pointer to buffer
// IN ULONG SystemInformationLength, // buffer size in bytes
// OUT PULONG ReturnLength OPTIONAL // pointer to a 32-bit
// // variable that receives
// // the number of bytes
// // written to the buffer
// );
typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);
PROCNTQSI NtQuerySystemInformation;
void main(void)
{
SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
SYSTEM_TIME_INFORMATION SysTimeInfo;
SYSTEM_BASIC_INFORMATION SysBaseInfo;
double dbIdleTime;
double dbSystemTime;
LONG status;
LARGE_INTEGER liOldIdleTime = {0,0};
LARGE_INTEGER liOldSystemTime = {0,0};
NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(
GetModuleHandle("ntdll"),
"NtQuerySystemInformation"
);
if (!NtQuerySystemInformation)
return;
// get number of processors in the system
status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL);
if (status != NO_ERROR)
return;
printf("\nCPU Usage (press any key to exit): ");
while(!_kbhit())
{
// get new system time
status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0);
if (status!=NO_ERROR)
return;
// get new CPU's idle time
status = NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL);
if (status != NO_ERROR)
return;
// 鏈枃杞嚜 C Builder鐮旂┒ - http://www.ccrun.com/article.asp?i=424&d=7jw23a
// if it's a first call - skip it
if (liOldIdleTime.QuadPart != 0)
{
// CurrentValue = NewValue - OldValue
dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
// CurrentCpuIdle = IdleTime / SystemTime
dbIdleTime = dbIdleTime / dbSystemTime;
// CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors 0.5;
printf("\b\b\b\b=%%",(UINT)dbIdleTime);
}
// store new CPU's idle and system time
liOldIdleTime = SysPerfInfo.liIdleTime;
liOldSystemTime = SysTimeInfo.liKeSystemTime;
// wait one second
Sleep(1000);
}
printf("\n");
}
//-------------------------------------------------------------
W9X:
#include <windows.h>
#include <conio.h>
#include <stdio.h>
void main(void)
{
HKEY hkey;
DWORD dwDataSize;
DWORD dwType;
DWORD dwCpuUsage;
// starting the counter
if ( RegOpenKeyEx( HKEY_DYN_DATA,
"PerfStats\\StartStat",
0,KEY_ALL_ACCESS,
&hkey ) != ERROR_SUCCESS)
return;
dwDataSize=sizeof(DWORD);
RegQueryValueEx( hkey,
"KERNEL\\CPUUsage",
NULL,&dwType,
(LPBYTE)&dwCpuUsage,
&dwDataSize );
RegCloseKey(hkey);
// geting current counter's value
if ( RegOpenKeyEx( HKEY_DYN_DATA,
"PerfStats\\StatData",
0,KEY_READ,
&hkey ) != ERROR_SUCCESS)
return;
printf("\nCPU Usage (press any key to exit): ");
while(!_kbhit())
{
dwDataSize=sizeof(DWORD);
RegQueryValueEx( hkey,
"KERNEL\\CPUUsage",
NULL,&dwType,
(LPBYTE)&dwCpuUsage,
&dwDataSize );
Sleep(500);
printf("\b\b\b\b=%%",dwCpuUsage);
}
printf("\n");
RegCloseKey(hkey);
// stoping the counter
if ( RegOpenKeyEx( HKEY_DYN_DATA,
"PerfStats\\StopStat",
0,KEY_ALL_ACCESS,
&hkey ) != ERROR_SUCCESS)
return;
dwDataSize=sizeof(DWORD);
RegQueryValueEx( hkey,
"KERNEL\\CPUUsage",
NULL,&dwType,
(LPBYTE)&dwCpuUsage,
&dwDataSize );
RegCloseKey(hkey);
}
NT/2000鏂規(guī)硶錛?br>
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#define SystemBasicInformation 0
#define SystemPerformanceInformation 2
#define SystemTimeInformation 3
#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 (double)((x).LowPart))
typedef struct
{
DWORD dwUnknown1;
ULONG uKeMaximumIncrement;
ULONG uPageSize;
ULONG uMmNumberOfPhysicalPages;
ULONG uMmLowestPhysicalPage;
ULONG uMmHighestPhysicalPage;
ULONG uAllocationGranularity;
PVOID pLowestUserAddress;
PVOID pMmHighestUserAddress;
ULONG uKeActiveProcessors;
BYTE bKeNumberProcessors;
BYTE bUnknown2;
WORD wUnknown3;
} SYSTEM_BASIC_INFORMATION;
typedef struct
{
LARGE_INTEGER liIdleTime;
DWORD dwSpare[76];
} SYSTEM_PERFORMANCE_INFORMATION;
typedef struct
{
LARGE_INTEGER liKeBootTime;
LARGE_INTEGER liKeSystemTime;
LARGE_INTEGER liExpTimeZoneBias;
ULONG uCurrentTimeZoneId;
DWORD dwReserved;
} SYSTEM_TIME_INFORMATION;
// ntdll!NtQuerySystemInformation (NT specific!)
//
// The function copies the system information of the
// specified type into a buffer
//
// NTSYSAPI
// NTSTATUS
// NTAPI
// NtQuerySystemInformation(
// IN UINT SystemInformationClass, // information type
// OUT PVOID SystemInformation, // pointer to buffer
// IN ULONG SystemInformationLength, // buffer size in bytes
// OUT PULONG ReturnLength OPTIONAL // pointer to a 32-bit
// // variable that receives
// // the number of bytes
// // written to the buffer
// );
typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);
PROCNTQSI NtQuerySystemInformation;
void main(void)
{
SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
SYSTEM_TIME_INFORMATION SysTimeInfo;
SYSTEM_BASIC_INFORMATION SysBaseInfo;
double dbIdleTime;
double dbSystemTime;
LONG status;
LARGE_INTEGER liOldIdleTime = {0,0};
LARGE_INTEGER liOldSystemTime = {0,0};
NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(
GetModuleHandle("ntdll"),
"NtQuerySystemInformation"
);
if (!NtQuerySystemInformation)
return;
// get number of processors in the system
status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL);
if (status != NO_ERROR)
return;
printf("\nCPU Usage (press any key to exit): ");
while(!_kbhit())
{
// get new system time
status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0);
if (status!=NO_ERROR)
return;
// get new CPU's idle time
status = NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL);
if (status != NO_ERROR)
return;
// 鏈枃杞嚜 C Builder鐮旂┒ - http://www.ccrun.com/article.asp?i=424&d=7jw23a
// if it's a first call - skip it
if (liOldIdleTime.QuadPart != 0)
{
// CurrentValue = NewValue - OldValue
dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
// CurrentCpuIdle = IdleTime / SystemTime
dbIdleTime = dbIdleTime / dbSystemTime;
// CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors 0.5;
printf("\b\b\b\b=%%",(UINT)dbIdleTime);
}
// store new CPU's idle and system time
liOldIdleTime = SysPerfInfo.liIdleTime;
liOldSystemTime = SysTimeInfo.liKeSystemTime;
// wait one second
Sleep(1000);
}
printf("\n");
}
//-------------------------------------------------------------
W9X:
#include <windows.h>
#include <conio.h>
#include <stdio.h>
void main(void)
{
HKEY hkey;
DWORD dwDataSize;
DWORD dwType;
DWORD dwCpuUsage;
// starting the counter
if ( RegOpenKeyEx( HKEY_DYN_DATA,
"PerfStats\\StartStat",
0,KEY_ALL_ACCESS,
&hkey ) != ERROR_SUCCESS)
return;
dwDataSize=sizeof(DWORD);
RegQueryValueEx( hkey,
"KERNEL\\CPUUsage",
NULL,&dwType,
(LPBYTE)&dwCpuUsage,
&dwDataSize );
RegCloseKey(hkey);
// geting current counter's value
if ( RegOpenKeyEx( HKEY_DYN_DATA,
"PerfStats\\StatData",
0,KEY_READ,
&hkey ) != ERROR_SUCCESS)
return;
printf("\nCPU Usage (press any key to exit): ");
while(!_kbhit())
{
dwDataSize=sizeof(DWORD);
RegQueryValueEx( hkey,
"KERNEL\\CPUUsage",
NULL,&dwType,
(LPBYTE)&dwCpuUsage,
&dwDataSize );
Sleep(500);
printf("\b\b\b\b=%%",dwCpuUsage);
}
printf("\n");
RegCloseKey(hkey);
// stoping the counter
if ( RegOpenKeyEx( HKEY_DYN_DATA,
"PerfStats\\StopStat",
0,KEY_ALL_ACCESS,
&hkey ) != ERROR_SUCCESS)
return;
dwDataSize=sizeof(DWORD);
RegQueryValueEx( hkey,
"KERNEL\\CPUUsage",
NULL,&dwType,
(LPBYTE)&dwCpuUsage,
&dwDataSize );
RegCloseKey(hkey);
}

Subject class and views from Observer. Any time the state of Subject is changed, it calls notify method which notifies all observers attached to the Subject.void Subject::notify()
{
for(int i=0; i<observes.size(); i++)
observers[i]->update();
}
Using Code
MySubject that has internal information connected to different views, it produces three different types of events called int_event, double_event and triple_event with different types and numbers of parameters.class MySubject
{
public:
CppEvent1<bool,int> int_event;
CppEvent2<bool,double,int> double_event;
CppEvent3<bool,double,int,const char*> triple_event;
void submit_int()
{
int_event.notify(1);
}
void submit_double()
{
double_event.notify(10.5,100);
}
void submit_triple()
{
triple_event.notify(10.5,100,"Oh ye");
}
};
MyListener1 and MyListener2 are unrelated. The only requirement is for callback (delegate) methods to have parameters signature similar to corresponding CppEvent.class MyListener1
{
public:
bool update_int(int p)
{
Console::WriteLine(S"int update listener 1");
return true;
}
bool update_double(double p,int p1)
{
Console::WriteLine(S"double update listener 1");
return true;
}
bool update_triple(double p,int p1,const char* str)
{
Console::WriteLine(S"triple update listener 1");
return true;
}
};
class MyListener2
{
public:
bool fun(int p)
{
Console::WriteLine(S"int update listener 2");
return true;
}
};
MyListener1 and MyListener2 and connect their member functions to corresponding events in MySubject model.int main(void)
{
// create listeners (viewers)
MyListener1* listener1 = new MyListener1;
MyListener2* listener2 = new MyListener2;
// create model
MySubject subject;
// connect different viewers to different events of the model
CppEventHandler h1 = subject.int_event.attach(listener1,
&MyListener1::update_int);
CppEventHandler h2 = subject.int_event.attach(listener2,
&MyListener2::fun);
CppEventHandler h3 = subject.double_event.attach(listener1,
&MyListener1::update_double);
CppEventHandler h4 = subject.triple_event.attach(listener1,
&MyListener1::update_triple);
// generate events
subject.submit_int();
subject.submit_double();
subject.submit_triple();
// detach handlers
subject.int_event.detach(h1);
subject.int_event.detach(h2);
subject.double_event.detach(h3);
subject.triple_event.detach(h4);
return 0;
}
> int update listener 1
> int update listener 2
> double update listener 1
> triple update listener 1
Implementation
// Event handler base for delegate with 1 parameter
template <typename ReturnT,typename ParamT>
class EventHandlerBase1
{
public:
virtual ReturnT notify(ParamT param) = 0;
};
template <typename ListenerT,typename ReturnT,typename ParamT>
class EventHandler1 : public EventHandlerBase1<ReturnT,ParamT>
{
typedef ReturnT (ListenerT::*PtrMember)(ParamT);
ListenerT* m_object;
PtrMember m_member;
public:
EventHandler1(ListenerT* object, PtrMember member)
: m_object(object), m_member(member)
{}
ReturnT notify(ParamT param)
{
return (m_object->*m_member)(param);
}
};
notify method is called. Detach method is used to release handler from the map.template <typename ReturnT,typename ParamT>
class CppEvent1
{
typedef std::map<int,EventHandlerBase1<ReturnT,ParamT> *> HandlersMap;
HandlersMap m_handlers;
int m_count;
public:
CppEvent1()
: m_count(0) {}
template <typename ListenerT>
CppEventHandler attach(ListenerT* object,ReturnT (ListenerT::*member)(ParamT))
{
typedef ReturnT (ListenerT::*PtrMember)(ParamT);
m_handlers[m_count] = (new EventHandler1<ListenerT,
ReturnT,ParamT>(object,member));
m_count++;
return m_count-1;
}
bool detach(CppEventHandler id)
{
HandlersMap::iterator it = m_handlers.find(id);
if(it == m_handlers.end())
return false;
delete it->second;
m_handlers.erase(it);
return true;
}
ReturnT notify(ParamT param)
{
HandlersMap::iterator it = m_handlers.begin();
for(; it != m_handlers.end(); it++)
{
it->second->notify(param);
}
return true;
}
};
Comments

銆銆銆 created:銆銆銆 2006/07/20
銆銆銆 filename:銆銆銆銆 Observer.h
銆銆銆 author:銆銆銆銆銆銆銆 鏉庡垱
銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆 http://m.shnenglu.com/converse/
#define OBSERVER_H
{
public:
銆銆銆 Subject() : m_nSubjectState(-1){}
銆銆銆 virtual ~Subject();
銆銆銆 void Detach(Observer *pObserver);銆銆銆銆銆銆銆 // 鍒犻櫎瀵硅薄
銆銆銆 STATE m_nSubjectState;銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆 // 妯℃嫙淇濆瓨Subject鐘舵佺殑鍙橀噺
銆銆銆 std::list<Observer*>銆銆銆 m_ListObserver;銆銆銆 // 淇濆瓨Observer鎸囬拡鐨勯摼琛?br>};
class Observer
{
public:
銆銆銆 Observer() : m_nObserverState(-1){}
銆銆銆 virtual ~Observer(){}
銆銆銆 virtual void Update(Subject* pSubject) = 0;
銆銆銆 STATE m_nObserverState;銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆 // 妯℃嫙淇濆瓨Observer鐘舵佺殑鍙橀噺
};
銆銆銆 : public Subject
{
public:
銆銆銆 ConcreateSubject() : Subject(){}
銆銆銆 virtual ~ConcreateSubject(){}
class ConcreateObserver
銆銆銆 : public Observer
{
public:
銆銆銆 ConcreateObserver() : Observer(){}
銆銆銆 virtual ~ConcreateObserver(){}
};
銆銆銆 created:銆銆銆 2006/07/20
銆銆銆 filename:銆銆銆銆 Observer.cpp
銆銆銆 author:銆銆銆銆銆銆銆 鏉庡垱
銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆 http://m.shnenglu.com/converse/
#include <iostream>
#include <algorithm>
|銆銆銆 Subject綾繪垚鍛樺嚱鏁扮殑瀹炵幇
|
銆----------------------------------------------------------------------*/
{
銆銆銆 std::cout << "Attach an Observern";
}
{
銆銆銆 std::list<Observer*>::iterator iter;
銆銆銆 iter = std::find(m_ListObserver.begin(), m_ListObserver.end(), pObserver);
銆銆銆 {
銆銆銆銆銆銆銆 m_ListObserver.erase(iter);
銆銆銆 }
}
{
銆銆銆 std::cout << "Notify Observers''s Staten";
銆銆銆銆銆銆銆銆 iter1 != iter2;
銆銆銆銆銆銆銆銆 ++iter1)
銆銆銆 {
銆銆銆銆銆銆銆 (*iter1)->Update(this);
銆銆銆 }
}
{
銆銆銆 std::cout << "SetState By Subjectn";
銆銆銆 m_nSubjectState = nState;
}
{
銆銆銆 std::cout << "GetState By Subjectn";
銆銆銆 return m_nSubjectState;
}
{
銆銆銆 std::list<Observer*>::iterator iter1, iter2, temp;
銆銆銆銆銆銆銆 iter1 != iter2;
銆銆銆銆銆銆銆 )
銆銆銆 {
銆銆銆銆銆銆銆 temp = iter1;
銆銆銆銆銆銆銆 ++iter1;
銆銆銆銆銆銆銆 delete (*temp);
銆銆銆 }
}
|銆銆銆 ConcreateSubject綾繪垚鍛樺嚱鏁扮殑瀹炵幇
|
----------------------------------------------------------------------*/
void ConcreateSubject::SetState(STATE nState)
{
銆銆銆 std::cout << "SetState By ConcreateSubjectn";
銆銆銆 m_nSubjectState = nState;
}
{
銆銆銆 std::cout << "GetState By ConcreateSubjectn";
銆銆銆 return m_nSubjectState;
}
|銆銆銆 ConcreateObserver綾繪垚鍛樺嚱鏁扮殑瀹炵幇
|
----------------------------------------------------------------------*/
void ConcreateObserver::Update(Subject* pSubject)
{
銆銆銆 if (NULL == pSubject)
銆銆銆銆銆銆銆 return;
}
3錛塎ain.cpp
銆銆銆 created:銆銆銆 2006/07/21
銆銆銆 filename:銆銆銆銆 Main.cpp
銆銆銆 author:銆銆銆銆銆銆銆 鏉庡垱
銆銆銆銆銆銆銆銆銆銆銆銆銆銆銆 http://m.shnenglu.com/converse/
#include <iostream>
{
銆銆銆 Observer *p1 = new ConcreateObserver;
銆銆銆 Observer *p2 = new ConcreateObserver;
銆銆銆 p->Attach(p1);
銆銆銆 p->Attach(p2);
銆銆銆 p->SetState(4);
銆銆銆 p->Notify();
銆銆銆 p->SetState(10);
銆銆銆 p->Notify();
}
鎴戝湪瀹炵幇涓縐?C++ 綾葷殑瀹炰緥鐨勫簭鍒楀寲宸ュ叿鏃訛紝渚濊禆浜嗗唴瀛樺竷灞銆傛垜鐭ラ亾甯傞潰涓婂緢澶?#8220;搴忓垪鍖?#8221;宸ュ叿鍏佽鏇翠負騫挎硾鐨勯氫俊鐢ㄩ旓紝浣嗘槸瀹冧滑涔熸槸鐢ㄨ搗鏉ユ渶楹葷儲鐨勶紝鏈夊緢澶氶檺鍒舵潯浠躲傛垜瀹炵幇鐨勫簭鍒楀寲宸ュ叿鐢ㄦ剰寰堟槑鏄撅紝涓虹壒瀹氳繍琛屾ā鍧楁彁渚涗究鎹烽珮鏁堢殑鎸佷箙鍖栧瓨鍌ㄨ兘鍔涖?br>
涓轟簡鎻愪緵鎰熸х殑璁よ瘑錛屾彁渚涗簡涓涓嬌鐢ㄨ繖涓簭鍒楀寲宸ュ叿鐨勭被鍨嬪畾涔夈?br>
class StorageDoc
: public SerialOwner
{
public:
Serializable(StorageDoc);
char c;
int i;
SerialString str;
};
瀹冪戶鎵胯嚜 SerialOwner錛屽畠澹版槑浜?Serializable錛岄殣鍚潃瀹炵幇浜嗕竴浜涙帴鍙o紝涓哄熀綾昏闂綋鍓嶇被鍨嬩俊鎭彁渚涘府鍔┿傝繖鏄緝鏃╀功鍐欑殑涓縐嶆柟妗堬紝鐜板湪鎴戜細鏀圭敤妯℃澘浠ヤ究鍦ㄧ紪璇戞椂寤虹珛綾誨瀷淇℃伅錛屼笉榪囧師鐞嗗畬鍏ㄤ竴鏍楓?br>
鐜板湪錛孲torageDoc 褰撲腑鐨勫唴瀛樺竷灞闇瑕佸彲紜畾鐨勶紝浣嗘槸鐢ㄦ埛浼氶夋嫨涓嶅悓鐨勭粨鏋勬垚鍛樺榻愰夐」錛屼負姝ら渶瑕佽瀹氫竴涓粨鏋勬垚鍛樺榻愮殑“瀛愬煙”錛屽畬鎴愯繖欏硅兘鍔涚殑浼寚浠ゆ槸 #pragma pack銆?br>
#pragma pack( [ show ] | [ push | pop ] [, identifier ] , n )
1錛夊綋閫夌敤 show錛屽垯娣誨姞涓鏉¤鍛婁俊鎭紝鎸囩ず褰撳墠緙栬瘧鍩熷唴鐨勫榻愬睘鎬?br>2錛変粎浠呰緗?n錛屽垯閲嶅啓緙栬瘧鍣ㄩ夐」 /Zp錛屽茍褰卞搷鍒版澹版槑浠ヤ笅鐨勫悓涓涓紪璇戝崟鍏冨唴鐨勬墍鏈夌粨鏋勫畾涔?br>3錛塸ush 浠ュ強 pop 綆$悊浜嗕竴緇?#8220;瀛愬煙”鍫嗘爤錛屽彲浠ヤ笉鏂姞娣卞祵濂?br>4錛塱dentifier 鍛藉悕浜嗗爢鏍堜笂鐨勫榻愰」錛屼互渚垮湪鐗瑰畾闇姹備腑寮瑰嚭鍚堥傜殑欏圭洰
浠ヤ笅鏄嬌鐢ㄧ殑娉ㄦ剰浜嬮」錛?br>
1錛変笉璁轟綍鏃訛紝#pragma pack() 鎬繪槸鎭㈠鍒?/Zp 鐨勯璁懼鹼紝鍗充嬌澶勪簬 push 鐨?#8220;瀛愬煙”
2錛?pragma pack(push) 鏈寚瀹氬榻愬鹼紝鍒欎笉鏀瑰彉
3錛?pragma pack(pop) 鍙寚瀹氬榻愬煎嚭鏍堝悗鐨勮緗鹼紝鑻ヤ笉鎸囧畾鍒欐寜宓屽絳夌駭榪樺師錛岀洿鑷?/Zp 棰勮鍊?br>
緇間笂錛?pragma pack(pop) 鎬繪槸鑳芥紜洖閫鍒頒笂涓涓綔鐢ㄥ煙錛屼笉綆¤浣滅敤鍩熼氳繃 #pragma pack(n) 澹版槑鎴栬?#pragma pack(push, n)銆傝?#pragma pack() 鎬繪槸鍙栭璁懼箋傚浜庣敤鎴蜂簨鍏堟寚瀹氫簡涓涓?#8220;瀛愬煙”錛屽茍鍦ㄥ叾涓紩鍏ヤ簡涓涓嬌鐢?#pragma pack(n) - #pragma pack() 瀵硅岄潪鍫嗘爤褰㈠紡鏉ュ0鏄庡眬閮ㄧ粨鏋勬垚鍛樺榻愮殑澶存枃浠訛紝浼氫嬌鐢ㄦ埛闈炲父鍥版儜銆?d3d9types.h> 灝辨槸榪欐牱鍋氱殑銆?br>
褰撴垜浠負紼嬪簭搴撶紪璇戣繍琛屾椂錛屾湁涓浜涚被鍨嬭姹備弗鏍煎湴閬靛畧鍐呭瓨甯冨眬錛屾瘮濡備竴浜涚‖浠跺厑璁告垜浠紶鍏ョ殑鏁版嵁灝遍渶瑕佽繖涔堝仛錛屽氨鍙互鎶婂畠浠檺瀹氳搗鏉ワ細
#pragma pack(push, 8)
#include "Chain.h"
#include "ByteQueue.h"
#include "SerialOwner.h"
#include "SerialUser.h"
#include "SerialString.h"
#include "SerialStream.h"
#pragma pack(pop)
浜嬫儏鍐嶅洖鍒板簭鍒楀寲涓婇潰錛岀敤鎴蜂細澶氭灝濊瘯緙栬瘧浠栦滑鐨勫簭鍒楀寲搴旂敤妯″潡錛屽茍鎸囨湜鍓嶄竴嬈$紪璇戜箣鍚庤繍琛屾墍浜х敓鐨勬枃浠朵粛鐒舵槸鍙敤鐨勶紝鎵浠ヨ繕闇瑕佸湪鐢ㄦ埛鏂囦歡褰撲腑鏄庣‘鎵閫夌敤鐨勫榻愬鹼紝騫朵竴鏃︾‘瀹氬氨涓嶅啀鏇存敼錛?br>
#pragma pack(push, 8)
class StorageDoc
: public SerialOwner
{
public:
Serializable(StorageDoc);
char c;
int i;
SerialString str;
};
#pragma pack(pop)
騫朵嬌鐢ㄥ畠浠細
StorageDoc doc;
doc.Load(t("doc.bin"));
std::cout << doc.str.Get() << std::endl;
doc.str = ss.str();
std::cout << doc.str.Get() << std::endl;
doc.Save(t("doc.bin"));
榪欏氨鏄叏閮ㄤ簡錛屼絾鏄濡備互涓婃彁鍒扮殑錛屼笉浠呬粎鍦ㄥ簭鍒楀寲涓婏紝鍜岀‖浠躲侀摼鎺ュ簱鐨勯氫俊涔熷彲鑳藉瓨鍦ㄤ弗鏍肩殑鍐呭瓨甯冨眬鐨勮姹傦紝濡傛灉浣犲湪欏圭洰璁捐涓婇伃閬囪繖浜涘洶鎯戯紝閭d箞鐜板湪灝卞彲浠ョ珛鍗沖姩鎵嬭В鍐沖畠浠?br>
濡傛灉瀵規(guī)湰鏂囨彁鍒扮殑搴忓垪鍖栬兘鍔涙劅鍏磋叮鐨勮瘽錛屽彲浠ュ埌浠ヤ笅閾炬帴浜嗚В璇︽儏錛?br>
http://code.google.com/p/los-lib/source/browse/
鐩綍鏄細
svn/trunk/Inc/Los/
鏂囦歡鍒嗗埆鏄細
_ISerialUser.h
ByteQueue.h
Chain.h
Serialization.h
SerialOwner.h
SerialStream.h
SerialString.h
SerialUser.h
涓嶈繃鍦ㄦ湰鏂囧彂甯冧箣鏃訛紝浠ヤ笂鏂囦歡鎵澶勭増鏈病鏈夐拡瀵圭粨鏋勬垚鍛樺榻愰夐」榪涜淇敼錛屼絾騫朵笉褰卞搷闃呰銆?br>
* 琛ュ厖涓錛?009-1-18 02:41錛?br>
鑱斿悎浠ュ強緇撴瀯鐨勭粨鏋勬垚鍛樺榻愬紓甯?br>
class Tick
{
static int _StaticID;
__int64 _StartLI; // __alignof(LARGE_INTEGER) != __alignof(__int64)
__int64 _CurrentLI;
__int64 _Frequency;
int _ID;
clock_t _Start;
clock_t _Current;
bool _Stop;
bool _HighPerformance;
...
}
LARGE_INTEGER 鏄垎鍒搴斾袱涓?32bit 浠ュ強涓涓?64bit 綾誨瀷鐨勮仈鍚堬紝濂囨殑鏄殢鐫鍏ㄥ眬瀵歸綈閫夐」鐨勪慨鏀癸紝LARGE_INTEGER 綾誨瀷鏈韓鐨勮姹傚榻?__alignof(LARGE_INTEGER) 灝嗗彇鑱斿悎鐨勬垚鍛樼殑鏈澶ц呭悓鍏ㄥ眬瀵歸綈閫夐」鐨勬渶灝忓鹼紝涔熷氨鏄錛屽綋 /Zp 璁劇疆涓?2錛岄偅涔?LARGE_INTEGER 涔熷皢浠呮壙璇哄湪 2 瀛楄妭杈圭晫涓婂榻愶紝澶氫箞涓嶅垢鍟娿傚綋鐒跺鏋滃皢榪欎釜綾誨瀷綰沖叆 #pragma pack 鐨勯檺瀹氬煙閭e氨浠涔堥棶棰橀兘娌℃湁浜嗭紝涓嶇鑱斿悎鐨勫榻愮畻娉曞涔堢殑鍙ゆ紝鍙淇濊瘉涓嶄慨鏀規(guī)墍闇鐨勫榻愬奸偅灝嗘繪槸鑳借幏寰楃‘瀹氱殑鍐呭瓨甯冨眬銆?br>
涓嶈繃姝e涓婇潰鐨勪唬鐮佸垪鍑虹殑錛屾垜浣跨敤浜?__int64 浠f浛浜?LARGE_INTEGER 鐨勫伐浣滐紝騫跺湪璇鋒眰 Win32 API 鐨勬帴鍙d笂寮哄埗鎸囬拡杞瀷錛屼嬌鐢ㄧ殑鏃跺欎害濡傛錛屼絾鑻ヨ闂仈鍚堟垚鍛樺垰濂戒負 __int64 綾誨瀷鍒欑洿鎺ヤ嬌鐢ㄤ究鍙傝繖縐嶆柟寮忔病鏈夎幏寰楅澶栫殑濂藉錛岀畻鏄竴縐嶆姉璁殑琛屼負錛屽茍涓旇鍚庢潵鐨勯槄璇昏呮湁鏈轟細浜嗚В鍒拌繖涓涓嶅緱鍏夌殑闂銆?br>
_HighPerformance = ::QueryPerformanceFrequency((LARGE_INTEGER*)&_Frequency) != 0;
褰撶劧浣滀負涓ヨ們鐨勪唬鐮佸啓浣滆咃紝涔熻浣犲皢鍦ㄤ笉姝竴澶勪嬌鐢ㄥ埌 LARGE_INTEGER錛屼負姝ゆ垜涔熶笉鎷掔粷浣跨敤濡備笅鏍煎紡錛?br>
#pragma pack(push, 8)
#include
#pragma pack(pop)
瀹冨彲淇濊瘉浣犱竾鏃犱竴澶便?br>
浣滀負瀵規(guī)瘮錛孎ILETIME 鏈夊涓嬪畾涔夛細
typedef struct _FILETIME
{
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME;
涓斾笉璁哄畠鎵闇鐨勫彲鑳界殑鏈澶х粨鏋勬垚鍛樺榻愪負 4錛屽畠涔熷皢浼撮殢鐫 /Zp 鐨勬洿鏀硅屽彉鍔ㄣ傚洜姝わ紝鍦ㄤ笉鍚岀殑閫夐」鐨勫獎鍝嶄笅錛?br>
__alignof(LARGE_INTEGER) != __alignof(FILETIME) != __alignof(__int64)
鏈変簺浜哄彲鑳借鎸囪矗浼氬彂鐢熻繖鏍風殑闂綰補鏄敤鎴峰湪鐜╁紕“緇撴瀯鎴愬憳瀵歸綈閫夐」”鑰屽鑷寸殑錛屾垜鐪熷笇鏈涗粬鑳藉璇諱竴璇昏繖綃囨枃绔犮?br>
* 琛ュ厖浜岋紙2009-1-18 02:41錛?br>
D3D 涓庣敤鎴峰畾涔夌粨鏋勭殑鍗忚皟
class VertexXYZ_N_T1
{
public:
float x, y, z;
float normal_x, normal_y, normal_z;
float u, v;
DeviceBitmap* bitmap;
Material* material;
float temp_val;
static const int FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
};
榪欐槸涓涓嚜瀹氫箟欏剁偣緇撴瀯錛屽畠鐨勬渶澶ф垚鍛樺瓧鑺傛暟涓?4錛屾墍鏈夌殑鎴愬憳涔熼兘鏄?4 瀛楄妭杈圭晫錛屼笉璁轟綔浣曢夐」錛屽緇堜繚鎸佺揣鍑戝瓨鍌紝鑻ュ叾涓竴涓垚鍛樻墿灞曚負 8 瀛楄妭錛岄偅涔堜即闅忕潃閫夐」鐨勬洿鏀癸紝VertexXYZ_N_T1 瑕佹眰鐨勫榻愯竟鐣屽彲瀵艱嚧閮ㄥ垎絀烘礊錛屼粠鑰屽悓紜歡鎵闇鐨勯《鐐圭紦瀛樻暟鎹竷灞瀛樺湪鍑哄叆錛屾垜涓嶈拷絀剁‖浠舵槸鍚︿嬌鐢?double 鍊鹼紝浣嗘槸鐜板湪灝卞簲褰撲嬌鐢?br>
#pragma pack(push, 4)
...
#pragma pack(pop)
鍔犱互闄愬畾銆?br>
鎴戣繕瀹氫箟浜?Matrix, Material, Vector3, Colorf 絳夌被鍨嬶紝濡傛灉瑕佷嬌寰楄繖浜涙暟鎹悓 D3D, D3DX 鐨勭浉搴旂被鍨嬪湪鍐呭瓨涓婂吋瀹圭殑錛屼篃鏄渶瑕侀檺瀹氱殑銆?/p>
1銆?sizeof搴旂敤鍦ㄧ粨鏋勪笂鐨勬儏鍐?/font>
璇風湅涓嬮潰鐨勭粨鏋勶細
struct MyStruct
{
double dda1;
char dda;
int type
};
瀵圭粨鏋凪yStruct閲囩敤sizeof浼氬嚭鐜頒粈涔堢粨鏋滃憿錛焥izeof(MyStruct)涓哄灝戝憿錛熶篃璁鎬綘浼氳繖鏍鋒眰錛?/font>
sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13
浣嗘槸褰撳湪VC涓祴璇曚笂闈㈢粨鏋勭殑澶у皬鏃訛紝浣犱細鍙戠幇sizeof(MyStruct)涓?6銆備綘鐭ラ亾涓轟粈涔堝湪VC涓細寰楀嚭榪欐牱涓涓粨鏋滃悧錛?/font>
鍏跺疄錛岃繖鏄疺C瀵瑰彉閲忓瓨鍌ㄧ殑涓涓壒孌婂鐞嗐備負浜嗘彁楂楥PU鐨勫瓨鍌ㄩ熷害錛孷C瀵逛竴浜涘彉閲忕殑璧峰鍦板潃鍋氫簡“瀵歸綈”澶勭悊銆傚湪榛樿鎯呭喌涓嬶紝VC瑙勫畾鍚勬垚鍛樺彉閲忓瓨鏀劇殑璧峰鍦板潃鐩稿浜庣粨鏋勭殑璧峰鍦板潃鐨勫亸縐婚噺蹇呴』涓鴻鍙橀噺鐨勭被鍨嬫墍鍗犵敤鐨勫瓧鑺傛暟鐨勫嶆暟銆備笅闈㈠垪鍑哄父鐢ㄧ被鍨嬬殑瀵歸綈鏂瑰紡(vc6.0,32浣嶇郴緇?銆?/font>
綾誨瀷
瀵歸綈鏂瑰紡錛堝彉閲忓瓨鏀劇殑璧峰鍦板潃鐩稿浜庣粨鏋勭殑璧峰鍦板潃鐨勫亸縐婚噺錛?/font>
Char
鍋忕Щ閲忓繀欏諱負sizeof(char)鍗?鐨勫嶆暟
int
鍋忕Щ閲忓繀欏諱負sizeof(int)鍗?鐨勫嶆暟
float
鍋忕Щ閲忓繀欏諱負sizeof(float)鍗?鐨勫嶆暟
double
鍋忕Щ閲忓繀欏諱負sizeof(double)鍗?鐨勫嶆暟
Short
鍋忕Щ閲忓繀欏諱負sizeof(short)鍗?鐨勫嶆暟
鍚勬垚鍛樺彉閲忓湪瀛樻斁鐨勬椂鍊欐牴鎹湪緇撴瀯涓嚭鐜扮殑欏哄簭渚濇鐢寵絀洪棿錛屽悓鏃舵寜鐓т笂闈㈢殑瀵歸綈鏂瑰紡璋冩暣浣嶇疆錛岀┖緙虹殑瀛楄妭VC浼氳嚜鍔ㄥ~鍏呫傚悓鏃禫C涓轟簡紜繚緇撴瀯鐨勫ぇ灝忎負緇撴瀯鐨勫瓧鑺傝竟鐣屾暟錛堝嵆璇ョ粨鏋勪腑鍗犵敤鏈澶х┖闂寸殑綾誨瀷鎵鍗犵敤鐨勫瓧鑺傛暟錛夌殑鍊嶆暟錛屾墍浠ュ湪涓烘渶鍚庝竴涓垚鍛樺彉閲忕敵璇風┖闂村悗錛岃繕浼氭牴鎹渶瑕佽嚜鍔ㄥ~鍏呯┖緙虹殑瀛楄妭銆?/font>
涓嬮潰鐢ㄥ墠闈㈢殑渚嬪瓙鏉ヨ鏄嶸C鍒板簳鎬庝箞鏍鋒潵瀛樻斁緇撴瀯鐨勩?/font>
struct MyStruct
{
double dda1;
char dda;
int type
}錛?/font>
涓轟笂闈㈢殑緇撴瀯鍒嗛厤絀洪棿鐨勬椂鍊欙紝VC鏍規(guī)嵁鎴愬憳鍙橀噺鍑虹幇鐨勯『搴忓拰瀵歸綈鏂瑰紡錛屽厛涓虹涓涓垚鍛榙da1鍒嗛厤絀洪棿錛屽叾璧峰鍦板潃璺熺粨鏋勭殑璧峰鍦板潃鐩稿悓錛堝垰濂藉亸縐婚噺0鍒氬ソ涓簊izeof(double)鐨勫嶆暟錛夛紝璇ユ垚鍛樺彉閲忓崰鐢╯izeof(double)=8涓瓧鑺傦紱鎺ヤ笅鏉ヤ負絎簩涓垚鍛榙da鍒嗛厤絀洪棿錛岃繖鏃朵笅涓涓彲浠ュ垎閰嶇殑鍦板潃瀵逛簬緇撴瀯鐨勮搗濮嬪湴鍧鐨勫亸縐婚噺涓?錛屾槸sizeof(char)鐨勫嶆暟錛屾墍浠ユ妸dda瀛樻斁鍦ㄥ亸縐婚噺涓?鐨勫湴鏂規(guī)弧瓚沖榻愭柟寮忥紝璇ユ垚鍛樺彉閲忓崰鐢╯izeof(char)=1涓瓧鑺傦紱鎺ヤ笅鏉ヤ負絎笁涓垚鍛榯ype鍒嗛厤絀洪棿錛岃繖鏃朵笅涓涓彲浠ュ垎閰嶇殑鍦板潃瀵逛簬緇撴瀯鐨勮搗濮嬪湴鍧鐨勫亸縐婚噺涓?錛屼笉鏄痵izeof(int)=4鐨勫嶆暟錛屼負浜嗘弧瓚沖榻愭柟寮忓鍋忕Щ閲忕殑綰︽潫闂錛孷C鑷姩濉厖3涓瓧鑺傦紙榪欎笁涓瓧鑺傛病鏈夋斁浠涔堜笢瑗匡級錛岃繖鏃朵笅涓涓彲浠ュ垎閰嶇殑鍦板潃瀵逛簬緇撴瀯鐨勮搗濮嬪湴鍧鐨勫亸縐婚噺涓?2錛屽垰濂芥槸sizeof(int)=4鐨勫嶆暟錛屾墍浠ユ妸type瀛樻斁鍦ㄥ亸縐婚噺涓?2鐨勫湴鏂癸紝璇ユ垚鍛樺彉閲忓崰鐢╯izeof(int)=4涓瓧鑺傦紱榪欐椂鏁翠釜緇撴瀯鐨勬垚鍛樺彉閲忓凡緇忛兘鍒嗛厤浜嗙┖闂達紝鎬葷殑鍗犵敤鐨勭┖闂村ぇ灝忎負錛?+1+3+4=16錛屽垰濂戒負緇撴瀯鐨勫瓧鑺傝竟鐣屾暟錛堝嵆緇撴瀯涓崰鐢ㄦ渶澶х┖闂寸殑綾誨瀷鎵鍗犵敤鐨勫瓧鑺傛暟sizeof(double)=8錛夌殑鍊嶆暟錛屾墍浠ユ病鏈夌┖緙虹殑瀛楄妭闇瑕佸~鍏呫傛墍浠ユ暣涓粨鏋勭殑澶у皬涓猴細sizeof(MyStruct)=8+1+3+4=16錛屽叾涓湁3涓瓧鑺傛槸VC鑷姩濉厖鐨勶紝娌℃湁鏀句換浣曟湁鎰忎箟鐨勪笢瑗褲?/font>
涓嬮潰鍐嶄婦涓緥瀛愶紝浜ゆ崲涓涓嬩笂闈㈢殑MyStruct鐨勬垚鍛樺彉閲忕殑浣嶇疆錛屼嬌瀹冨彉鎴愪笅闈㈢殑鎯呭喌錛?/font>
struct MyStruct
{
char dda;
double dda1;
int type
}錛?/font>
榪欎釜緇撴瀯鍗犵敤鐨勭┖闂翠負澶氬ぇ鍛紵鍦╒C6.0鐜涓嬶紝鍙互寰楀埌sizeof(MyStruc)涓?4銆傜粨鍚堜笂闈㈡彁鍒扮殑鍒嗛厤絀洪棿鐨勪竴浜涘師鍒欙紝鍒嗘瀽涓媀C鎬庝箞鏍蜂負涓婇潰鐨勭粨鏋勫垎閰嶇┖闂寸殑銆傦紙綆鍗曡鏄庯級
struct MyStruct
{
char dda;//鍋忕Щ閲忎負0錛屾弧瓚沖榻愭柟寮忥紝dda鍗犵敤1涓瓧鑺傦紱
double dda1;//涓嬩竴涓彲鐢ㄧ殑鍦板潃鐨勫亸縐婚噺涓?錛屼笉鏄痵izeof(double)=8
//鐨勫嶆暟錛岄渶瑕佽ˉ瓚?涓瓧鑺傛墠鑳戒嬌鍋忕Щ閲忓彉涓?錛堟弧瓚沖榻?/font>
//鏂瑰紡錛夛紝鍥犳VC鑷姩濉厖7涓瓧鑺傦紝dda1瀛樻斁鍦ㄥ亸縐婚噺涓?
//鐨勫湴鍧涓婏紝瀹冨崰鐢?涓瓧鑺傘?/font>
int type錛?/涓嬩竴涓彲鐢ㄧ殑鍦板潃鐨勫亸縐婚噺涓?6錛屾槸sizeof(int)=4鐨勫?/font>
//鏁幫紝婊¤凍int鐨勫榻愭柟寮忥紝鎵浠ヤ笉闇瑕乂C鑷姩濉厖錛宼ype瀛?/font>
//鏀懼湪鍋忕Щ閲忎負16鐨勫湴鍧涓婏紝瀹冨崰鐢?涓瓧鑺傘?/font>
}錛?/鎵鏈夋垚鍛樺彉閲忛兘鍒嗛厤浜嗙┖闂達紝絀洪棿鎬葷殑澶у皬涓?+7+8+4=20錛屼笉鏄粨鏋?/font>
//鐨勮妭杈圭晫鏁幫紙鍗崇粨鏋勪腑鍗犵敤鏈澶х┖闂寸殑綾誨瀷鎵鍗犵敤鐨勫瓧鑺傛暟sizeof
//(double)=8錛夌殑鍊嶆暟錛屾墍浠ラ渶瑕佸~鍏?涓瓧鑺傦紝浠ユ弧瓚崇粨鏋勭殑澶у皬涓?/font>
//sizeof(double)=8鐨勫嶆暟銆?/font>
鎵浠ヨ緇撴瀯鎬葷殑澶у皬涓猴細sizeof(MyStruc)涓?+7+8+4+4=24銆傚叾涓葷殑鏈?+4=11涓瓧鑺傛槸VC鑷姩濉厖鐨勶紝娌℃湁鏀句換浣曟湁鎰忎箟鐨勪笢瑗褲?/font>
VC瀵圭粨鏋勭殑瀛樺偍鐨勭壒孌婂鐞嗙‘瀹炴彁楂楥PU瀛樺偍鍙橀噺鐨勯熷害錛屼絾鏄湁鏃跺欎篃甯︽潵浜嗕竴浜涢夯鐑︼紝鎴戜滑涔熷睆钄芥帀鍙橀噺榛樿鐨勫榻愭柟寮忥紝鑷繁鍙互璁懼畾鍙橀噺鐨勫榻愭柟寮忋?/font>
VC涓彁渚涗簡#pragma pack(n)鏉ヨ瀹氬彉閲忎互n瀛楄妭瀵歸綈鏂瑰紡銆俷瀛楄妭瀵歸綈灝辨槸璇村彉閲忓瓨鏀劇殑璧峰鍦板潃鐨勫亸縐婚噺鏈変袱縐嶆儏鍐碉細絎竴銆佸鏋渘澶т簬絳変簬璇ュ彉閲忔墍鍗犵敤鐨勫瓧鑺傛暟錛岄偅涔堝亸縐婚噺蹇呴』婊¤凍榛樿鐨勫榻愭柟寮忥紝絎簩銆佸鏋渘灝忎簬璇ュ彉閲忕殑綾誨瀷鎵鍗犵敤鐨勫瓧鑺傛暟錛岄偅涔堝亸縐婚噺涓簄鐨勫嶆暟錛屼笉鐢ㄦ弧瓚抽粯璁ょ殑瀵歸綈鏂瑰紡銆傜粨鏋勭殑鎬誨ぇ灝忎篃鏈変釜綰︽潫鏉′歡錛屽垎涓嬮潰涓ょ鎯呭喌錛氬鏋渘澶т簬鎵鏈夋垚鍛樺彉閲忕被鍨嬫墍鍗犵敤鐨勫瓧鑺傛暟錛岄偅涔堢粨鏋勭殑鎬誨ぇ灝忓繀欏諱負鍗犵敤絀洪棿鏈澶х殑鍙橀噺鍗犵敤鐨勭┖闂存暟鐨勫嶆暟錛?/font>
鍚﹀垯蹇呴』涓簄鐨勫嶆暟銆備笅闈婦渚嬭鏄庡叾鐢ㄦ硶銆?/font>
#pragma pack(push) //淇濆瓨瀵歸綈鐘舵?/font>
#pragma pack(4)//璁懼畾涓?瀛楄妭瀵歸綈
struct test
{
char m1;
double m4;
int m3;
};
#pragma pack(pop)//鎭㈠瀵歸綈鐘舵?/font>
浠ヤ笂緇撴瀯鐨勫ぇ灝忎負16錛屼笅闈㈠垎鏋愬叾瀛樺偍鎯呭喌錛岄鍏堜負m1鍒嗛厤絀洪棿錛屽叾鍋忕Щ閲忎負0錛屾弧瓚蟲垜浠嚜宸辮瀹氱殑瀵歸綈鏂瑰紡錛?瀛楄妭瀵歸綈錛夛紝m1鍗犵敤1涓瓧鑺傘傛帴鐫寮濮嬩負m4鍒嗛厤絀洪棿錛岃繖鏃跺叾鍋忕Щ閲忎負1錛岄渶瑕佽ˉ瓚?涓瓧鑺傦紝榪欐牱浣垮亸縐婚噺婊¤凍涓簄=4鐨勫嶆暟錛堝洜涓簊izeof(double)澶т簬n錛?m4鍗犵敤8涓瓧鑺傘傛帴鐫涓簃3鍒嗛厤絀洪棿錛岃繖鏃跺叾鍋忕Щ閲忎負12錛屾弧瓚充負4鐨勫嶆暟錛宮3鍗犵敤4涓瓧鑺傘傝繖鏃跺凡緇忎負鎵鏈夋垚鍛樺彉閲忓垎閰嶄簡絀洪棿錛屽叡鍒嗛厤浜?6涓瓧鑺傦紝婊¤凍涓簄鐨勫嶆暟銆傚鏋滄妸涓婇潰鐨?pragma pack(4)鏀逛負#pragma pack(16)錛岄偅涔堟垜浠彲浠ュ緱鍒扮粨鏋勭殑澶у皬涓?4銆傦紙璇瘋鑰呰嚜宸卞垎鏋愶級
2銆?sizeof鐢ㄦ硶鎬葷粨
鍦╒C涓紝sizeof鏈夌潃璁稿鐨勭敤娉曪紝鑰屼笖寰堝鏄撳紩璧蜂竴浜涢敊璇備笅闈㈡牴鎹畇izeof鍚庨潰鐨勫弬鏁板sizeof鐨勭敤娉曞仛涓葷粨銆?/font>
A錛?鍙傛暟涓烘暟鎹被鍨嬫垨鑰呬負涓鑸彉閲忋備緥濡俿izeof(int),sizeof(long)絳夌瓑銆傝繖縐嶆儏鍐佃娉ㄦ剰鐨勬槸涓嶅悓緋葷粺緋葷粺鎴栬呬笉鍚岀紪璇戝櫒寰楀埌鐨勭粨鏋滃彲鑳芥槸涓嶅悓鐨勩備緥濡俰nt綾誨瀷鍦?6浣嶇郴緇熶腑鍗?涓瓧鑺傦紝鍦?2浣嶇郴緇熶腑鍗?涓瓧鑺傘?/font>
B錛?鍙傛暟涓烘暟緇勬垨鎸囬拡銆備笅闈婦渚嬭鏄?
int a[50]; //sizeof(a)=4*50=200; 姹傛暟緇勬墍鍗犵殑絀洪棿澶у皬
int *a=new int[50];// sizeof(a)=4; a涓轟竴涓寚閽堬紝sizeof(a)鏄眰鎸囬拡
//鐨勫ぇ灝?鍦?2浣嶇郴緇熶腑錛屽綋鐒舵槸鍗?涓瓧鑺傘?/font>
C錛?鍙傛暟涓虹粨鏋勬垨綾匯係izeof搴旂敤鍦ㄧ被鍜岀粨鏋勭殑澶勭悊鎯呭喌鏄浉鍚岀殑銆備絾鏈変袱鐐歸渶瑕佹敞鎰忥紝絎竴銆佺粨鏋勬垨鑰呯被涓殑闈欐佹垚鍛樹笉瀵圭粨鏋勬垨鑰呯被鐨勫ぇ灝忎駭鐢熷獎鍝嶏紝鍥犱負闈欐佸彉閲忕殑瀛樺偍浣嶇疆涓庣粨鏋勬垨鑰呯被鐨勫疄渚嬪湴鍧鏃犲叧銆?/font>
絎簩銆佹病鏈夋垚鍛樺彉閲忕殑緇撴瀯鎴栫被鐨勫ぇ灝忎負1錛屽洜涓哄繀欏諱繚璇佺粨鏋勬垨綾葷殑姣忎竴
涓疄渚嬪湪鍐呭瓨涓兘鏈夊敮涓鐨勫湴鍧銆?/font>
涓嬮潰涓句緥璇存槑錛?/font>
Class Test{int a;static double c};//sizeof(Test)=4.
Test *s;//sizeof(s)=4,s涓轟竴涓寚閽堛?/font>
Class test1{ };//sizeof(test1)=1;
D錛?鍙傛暟涓哄叾浠栥備笅闈婦渚嬭鏄庛?/font>
int func(char s[5]);
{
cout<< sizeof(s) << endl;
//鏁扮粍鍙傛暟鍦ㄤ紶閫掔殑鏃跺欑郴緇熷鐞嗕負涓涓寚閽堬紝鎵
//浠izeof(s)瀹為檯涓婁負姹傛寚閽堢殑澶у皬銆?/font>
return 1;
}
sizeof(func(“1234”))=4//鍥犱負func鐨勮繑鍥炵被鍨嬩負int錛屾墍浠ョ浉褰撲簬
姹俿izeof(int).
浠ヤ笂涓簊izeof鐨勫熀鏈敤娉曪紝鍦ㄥ疄闄呯殑浣跨敤涓娉ㄦ剰鍒嗘瀽VC鐨勫垎閰嶅彉閲忕殑鍒嗛厤絳栫暐錛岃繖鏍風殑璇濆彲浠ラ伩鍏嶄竴浜涢敊璇?/font>