灝變緥濡備功涓殑Sample錛屽叧浜庢椂闂寸殑錛屾垜浠竴鑸殑鍋氭硶灝辨槸鍦ㄥ垱寤?/span>Day瀵硅薄鏃訛紝榪藉姞鏍¢獙鍑芥暟鏉ュ垽鏂勾鏈堟棩鏄笉鏄湁鏁堛?/span>
瀹氫箟錛?/span>
class Month {
public:
static Month Jan() {return Month(1); }
static Month feb() {return Month(2); }
…
private Month(int m);
};
Date d(Month::Mar(), Day(30), Year(1995) );
涓哄暐涓嶇洿鎺ヤ嬌鐢ㄩ潤鎬佸彉閲忥紵
鍙傝?/span>Item4 P30錛岀畝鍗曡灝辨槸涓嶈兘淇濊瘉鍦ㄤ嬌鐢?/span>non-local static objects鏃訛紝榪欎釜瀵硅薄灝卞凡緇忓垵濮嬪寲浜嗐傚鏋?/span>non-local static objects鍦ㄥ彟涓涓枃浠朵簡錛屽張鎭板閥娌℃湁鍒濆鍖栵紝緋葷粺褰撶劧灝變細緲樿精瀛愪簡銆?/span>
鍏堝弬鑰?/span>Item3 P19
class Rational { …};
const Rational operator*(const Rational &lhs, const Rational &rhs);
涔嬫墍浠ュ己鍒惰緗負const灝辨槸涓轟簡閬垮厤client鍦ㄤ嬌鐢ㄦ椂鍑洪敊銆傚洜涓哄鏋滄病鏈?/span>clien錛岄偅涔堬細
Rational a,b,c;
…
(a*b)=c
榪欑鍐欐硶鏄鐨勶紝浣嗘槸濡傛灉a錛?/span>b鏄唴緗被鍨嬶紝榪欑鍐欐硶灝辨槸閿欒鐨勩?/span>
闄ら潪鏈夊繀瑕侊紝鍚﹀垯灝辮淇濊瘉浣犵殑綾誨瀷type鐨勮涓哄拰鍐呯疆綾誨瀷涓鑷淬?/span>
STL鏄鏍鳳紝java鍦ㄨ繖閲屾垚浜嗗弽闈㈡暀鏉愶紝鍥犱負濡傛灉鎯崇煡閬撳鍣ㄥ唴瀵硅薄鐨勬暟閲忥紝鐢?/span>Array錛岃璁塊棶灞炴?/span>length錛?/span>String瑕佺敤length鍑芥暟錛?/span>ArrayList瑕佺敤size鍑芥暟錛岃繖灝辨槸涓嶄竴鑷存с?/span>
鎵懼嚭浠ヤ笅鍐欐硶鐨勪袱涓槗閿欑殑鍦版柟錛?/span>
Investment* createInvestment();
1 蹇樿鍒犻櫎createInvestment()榪斿洖鐨勬寚閽?/span>
2 鍒犻櫎榪欎釜鎸囬拡澶氭
so錛屼慨鏀瑰畾涔夛細
std::tr1::shared_ptr< Investment > createInvestment();
濡傛灉鍑虹幇榪欑鎯呭艦錛氫粠createInvestment寰楀埌Investment*鐨勫嚱鏁拌鎶婅繖涓寚閽堜紶閫掍釜緇欏彨鍋?/span>getRidOfInvestment錛岀敱getridOfInvestment鍙栦唬浣跨敤delete銆?/span>
榪欓噷灝卞嚭鐜頒簡涓涓柊鐨?/span>client鏄撻敊鐨勭偣錛岀敤鎴鋒垨璁鎬細浣跨敤閿欑殑璧勬簮閲婃斁鏈哄埗銆傚洜涓?/span>delete琚?/span>getRidOfInvestment鍙栦唬浜嗐?/span>
std::tr1::shared_ptr< Investment >
pInv(static_cast<Investment*>(0), getRidOfInvestment);
閭d箞瀹氫箟灝卞簲璇ユ槸榪欐牱鐨勶細
std::tr1::shared_ptr< Investment > createInvestment()
{
std::tr1::shared_ptr< Investment >
retVal(static_cast<Investment*>(0), getRidOfInvestment); //榪欎笉鑳借client鏉ュ仛
retVal = …;
return retVal;
}
tr1::shared_ptr鐨勪紭鐐規槸鍏佽鍦ㄤ竴涓?/span>DLL鍒涘緩瀵硅薄錛屽湪鍙︿竴涓?/span>DLL閲屽垹闄ゅ璞°?/span>
鍦ㄨ璁′竴涓被鐨勬椂鍊欙紝瑕佸洖絳斾竴緋誨垪鐨勯棶棰樺摝銆?/span>
鍙傝冨ぇ甯堝湪P85-P86涔嬮棿緇欏嚭鐨勫父甯哥殑娓呭崟鍚э紝鍏跺疄瀹為檯涓婏紝鎴戝湪璁捐綾葷殑鏃跺欑殑紜病鏈夋兂榪囪繖涔堝錛岄棶榪囪嚜宸辮繖涔堢殑涓轟粈涔堬紝鎵浠ヨ繖涔熸槸鎴戞繪槸鍦ㄨ拷姹備唬鐮侀噸鐢紝鍗存繪槸鍙戠幇鑷繁鍐欑殑浠g爜閲嶇敤搴﹀緢浣庣殑涓涓師鍥犳妸銆?/span>
But鍏堝涔犱竴涓崟璇嶏紝characteristic錛?/span>KAO錛岃繖绔熺劧鏄釜鍚嶈瘝銆?/span>
鍐嶅涓涓湴閬撶殑璇存硶錛氳В鍐抽棶棰樼殑鏂規硶錛?/span>The way around the slicing problem is…
鍑芥暟閮芥槸鍊間紶閫掋?/span>pass by-value銆?/span>function parameters are initialized with copies of the actual arguments, and function callers goes back a copy of the value returned by the function.榪欐牱褰撶劧寮閿灝卞ぇ浜嗭紝姣忔閮藉厛copy涓浠借繘鏉ワ紝瀹屼簨浠ュ悗錛屽啀copy涓浠藉嚭鍘匯?/span>
鍋囪鍑芥暟鐨勫弬鏁版槸涓涓?/span>Student瀵硅薄錛?/span>bool validateStudent(Student s);璋冪敤榪欎釜鍑芥暟錛?u>棰濆鐨勯殣鎬у紑閿鍖呮嫭瑕佸厛璋冪敤copy constructor鍒涘緩涓涓?/span>Student瀵硅薄鐢ㄤ簬鍑芥暟鍐呴儴錛屽嚱鏁版墽琛岀粨鏉熷啀璋冪敤鏋愭瀯鍑芥暟閲婃斁榪欎釜瀵硅薄銆?/span>
bool validateStudent(const Student& s);
寮曠敤鏄氳繃鎸囬拡鏉ュ疄鐜板疄鐜扮殑錛屽洜姝や紶閫掑紩鐢ㄥ疄闄呬笂灝辨槸鍦ㄤ紶閫掓寚閽堛?/span>references are typically implemented as pointers.
浣嗘槸榪欎釜瑙勫垯瀵逛簬鍐呯疆鏁版嵁綾誨瀷涓嶉傜敤錛屼篃涓嶆槸閫傜敤STL iterator鍜屽嚱鏁板璞?/span>function objects銆?/span>
鍗充嬌鍐嶅皬鐨勫璞′篃搴旇涓嶈浣跨敤鍊間紶閫掞紝鑰屾槸瑕佷嬌鐢?/span>pass by reference-to-const銆?/span>
slicing problem鏄湪澶氭佽鍒欓噷闈㈠鏄撲駭鐢熺殑銆?/span>
鐪嬩竴涓畝鍗曠殑鍩虹被銆佹淳鐢熺被鐨勫畾涔?/span>
class Window
{
public:
int height;
int width;
};
class TextWindow : public Window
{
public:
int cursorLocation;
};
…
Window win;
TextWindow *tWinPtr;
tWinPtr = new TextWindow;
win = *tWinprt;
win鏄竴涓?/span>Window瀵硅薄錛?/span>C++瑙勫畾錛氱粰win鍒嗛厤鐨勫唴瀛樼湅瑙佺殑澶у皬錛岀敱鍏墮潤鎬佺被鍨嬪喅瀹氥傚氨鏄榛樿鐨勬嫹璐濆嚱鏁板鑷翠俊鎭細鍑虹幇涓㈠け銆傝繖灝辨槸slicing problem銆?/span>
璇曟兂涓涓嬭繖瑕佹槸閫氳繃鍊間紶閫掔殑鏂瑰紡浼犻掑弬鏁幫紝瀹炲弬涓copy灝卞凡緇忎涪澶變俊鎭簡銆?/span>
鍫嗗拰鏍堣繖鏄?/span>2涓笉鍚岀殑姒傚康錛屽搸鍝燂紝鎴戜竴鐩翠互涓烘槸涓涓瘝銆?/span>
heap錛氬爢
stack錛氭爤
argument
(against) 浜夎錛屾剰瑙?/span>
瀹炲弬
褰㈠弬鏄?/span>parameters
榪欐槸涓涓吀鍨嬬殑渚嬪瓙錛?/span>
class WebBrowser {
public:
…
void clearCache();
void clearHistory();
void removeCookies();
…
};
涓轟簡鎻愪緵涓涓墽琛屾墍鏈夋搷浣滅殑鍑芥暟錛屾墍浠ュ氨鍦?/span>WebBrowser閲岄潰榪藉姞瀹氫箟錛?/span>
void clearEverything();
鍝庯紝鎴戜竴鐩村氨鏄繖涔堝啓鐨勶紝騫惰嚜浠ヤ負鏈夊緢濂界殑灝佽錛?/span>But
void clearBrowser(WebBrowser wb)
{
wb.clearCache();
wb.clearHistory();
wb.removeCookies();
}
絎竴錛氬墠鑰呭茍涓嶆瘮鍚庤呮湁寰堝ソ鐨勫皝瑁?/span>
榪欏氨瑕佽В閲婁竴涓嬩粈涔堝彨鍋?#8220;灝佽”錛熶互鍙婂皝瑁呯殑鍒ゅ埆鏍囧噯銆?/span>
灝佽鐨勫垽鍒爣鍑嗭細鍙互閫氳繃緇熻鑳藉璁塊棶榪欎釜data鐨勫嚱鏁扮殑鏁扮洰鏉ヨ綆楋紝鍑芥暟瓚婂錛岃繖涓?/span>data灝佽涔熷氨鏈堜笉濂斤紝鍥犳鍓嶄竴縐嶅啓娉曠殑灝佽灝辨病鏈夊悗鑰呭ソ銆傝繖涔熷彲浠ョ敤鏉ヨВ閲?/span>Item22閲岄潰錛屼負浠涔堣姹傛暟鎹垚鍛樹笉鑳藉畾涔変負public銆傚彟澶栧鍔?/span>clearEverything()浣滀負member function錛屽疄闄呬笂鏄檷浣庝簡灝佽鎬с傝屽悗闈㈢殑non-member non-friend functions鐨勫畾涔夊氨娌℃湁鏀瑰彉WebBrowser鐨勫皝瑁呮с?/span>
絎簩錛氬悗鑰呰繕鑳芥彁渚涙洿鍔犵伒媧葷殑鎵撳寘package錛屽鍔犳墿灞曟с?/span>
put all convenience functions in multiple header files, but one namespace.
絎笁錛氬鍔犲嚱鏁扮殑鍙墿灞曟с?/span>
浣犲彲浠ュ畾涔夎嚜宸辯殑convenience functions錛屽啓鍒頒竴涓?/span>header file閲岄潰錛屾斁鍒板悓涓涓?/span>namespace閲岄潰銆傝繖鏄?/span>member function鍋氫笉鍒扮殑銆?/span>
鍘熷洜錛?/span>
Parameters are eligible for implicit type conversion only if they are listed in the parameter list.
緇撹錛?/span>
make operator* a non-member function, thus allowing compilers to perform implicit type conversions on all arguments.
class Rational {
…
};
const Rational operatior*(const Rational& lhs, Rational& rhs)
{
return Rationan(lhs.numerator()*rhs.numerator(),
lhs.denominator()*rhs. denominator () );
}
涓涓鍖猴細
濡傛灉涓涓嚱鏁幫紝鍜屾煇涓被鐩稿叧錛岃屽張涓嶈兘瀹氫箟鎴?/span>member錛岄偅涔堣繖涓嚱鏁板氨涓瀹氳瀹氫箟鎴?/span>friend銆?/span>
涓婇潰榪欎釜渚嬪瓙灝辮鏄庤繖涓娉曞茍涓嶆紜傜湡鐖辯敓鍛斤紝鎱庣敤friend functions銆?/span>
灝辨槸鎸?/span>std閲岄潰瀹氫箟鐨?/span>swap
Widget錛?/span>:鎴戜滑甯屾湜鐨勬槸浜ゆ崲鎸囬拡錛屼絾swap瀹為檯鍋氱殑鏄笉浠?/span>copy浜?/span>3涓?/span>Widget瀵硅薄錛岃屼笖榪?/span>copy浜?/span>3涓?/span>WidgetImpl瀵硅薄銆傚お嫻垂浜嗭紒閮戒綆紕蟲椂浠d簡銆?/span>
class Widget{
void swap(Widget& other)
{
using std::swap;
swap(pImpl, other.pImpl;);
}
…
};
template<> void swap<Widget>( Widget& a, Widget&b)
{
a.wap(b);
}
鎺ヤ笅鏉ヨ璁ㄨ鐨勬槸濡傛灉Widget鍜?/span>WidgetImpl涓嶆槸綾昏屾槸綾繪ā鏉夸細鎬庝箞鏍鳳紵
綰︽潫鏉′歡錛氫笉鑳藉湪std閲岄潰澧炲姞鏂扮殑template錛屽彧鑳界壒鍖栵紙specialize錛?/span>std鍐呯殑template銆?/span>
濡傛灉闈炶瀹氫箟錛?/span>say sorry銆?/span>behavior is undefined銆?/span>KAO錛屽叾瀹炶繖姣斿紓甯歌繕璁ㄥ帉銆?/span>
瑙e喅鏂規硶鏄妸瀹冨畾涔夊埌涓涓嚜宸辯殑namespace閲岄潰錛岃屼笉瑕佸畾涔夊埌std閲岄潰銆?/span>
namespace WidgetStuff {
…
template<typename T>
class Widget{…};
…
template<typename T>
void swap(Widget<T>& a, Widget<T>& b)
{
a.swap(b);
}
}
濡傛灉浠呬粎鏄拡瀵逛竴涓?/span>class錛岄偅灝辯壒鍖?/span>std::swap銆?/span>
If you want to have your class-specializing version of swap called in as many contexts as possible, you need to write both a non-member version in the same namespace as your class and a specialization of std::swap.
榪欓儴鍒嗗崄鍒嗙粫錛?/span>P111榪樺浜?/span>C++鐨?/span>name lookup鐨勮鍒欒繘琛屼簡璇︾粏鐨勬弿榪般傚煎緱閲嶆柊娓╀範銆?/span>