#include<iostream> #include<vector> #include<algorithm> using namespace std; int main() { vector<double> v; double d; while(cin>>d) v.push_back(d); // read elements if (!cin.eof()) { // check if input failed cerr << "format error\n"; return 1; // error return } cout << "read " << v.size() << " elements\n"; reverse(v.begin(),v.end()); cout << "elements in reverse order:\n"; for (int i = 0; i<v.size(); ++i) cout << v[i] << '\n'; return 0; // success return }
#include<iostream> #include<vector> #include<algorithm> #include<string> using namespace std; int main() { vector<double> v; double d; while(cin>>d) v.push_back(d); // read elements if (!cin.eof()) { // check if input failed cin.clear(); // clear error state string s; cin >> s; // look for terminator string if (s != "end") { cerr << "format error\n"; return 1; // error return } } cout << "read " << v.size() << " elements\n"; reverse(v.begin(),v.end()); cout << "elements in reverse order:\n"; for (int i = 0; i<v.size(); ++i) cout << v[i] << '\n'; return 0; // success return }
音狛?匆嗤辛嬬圻咀壓噐低議殻會!!心心低議殻會譜柴珊嬬音嬬個序?園咎匂頁音頁葎阻乏旋恢竃屎鳩議屈序崙鷹遇音誼音郭序撹為倖遊猟周、叱嵐佩議坿旗鷹?圻夸貧?峪勣斤坿鷹癖輝單晒匯和?園咎産蛸議諒籾哘乎辛參盾畳。泌惚屏潤壓噐低議窃垂工哘斌?椎担低寄古茅阻^算匯社窃垂工哘斌 ?翌鳩糞短焚担辛恂議阻?徽泌惚諒籾壓噐低徭失議旗鷹?椎担頼畠辛參宥狛嶷更?refactoring?栖斑低議旗鷹厚葎潤更晒?貫遇聞坿鷹匯稀嗤厚個扮俶嶷園咎議旗鷹楚恷弌。宸劔議旗鷹吏吏頁厚挫議譜柴?咀葎万議添栽殻業熟詰?辛略擦來熟煮。
厘断栖心匯倖OOP議将灸箭徨?
class Shape { public: // interface to users of Shapes virtual void draw() const; virtual void rotate(int degrees); // ... protected: // common data (for implementers of Shapes) Point center; Color col; // ... }; class Circle : public Shape { public: void draw() const; void rotate(int) { } // ... protected: int radius; // ... }; class Triangle : public Shape { public: void draw() const; void rotate(int); // ... protected: Point a, b, c; // ... };
侭參?壓児窃嶄慧匯乂^斤噐写覚窃岻糞恬嗤逸廁 ?議孔嬬賜俯頁竃噐挫吭?徽糞夸頁醍軍議坿畑。喘薩議勣箔頁謹延議?侭參糞恬旗鷹匆頁謹延議。繍謹延議旗鷹慧壓俯謹写覚窃脅勣喘欺議児窃岻嶄?椎担延晒辛祥音頁蕉何議阻?宸氏夛撹畠蕉唹峒議?醤悶遇冱祥頁?児窃侭厥正議匯倖遊猟周延強阻?椎担侭嗤写覚窃侭壓議猟周脅俶嶷仟園咎。
宸劔蛍裂狛朔?盾畳岻祇祥?垓瘈彈藋烹砂欞?兒禎獏致焞ş蚣鶺長?化臙罍ii璐?斡埃務仞獏佯叩欝鎚久濹δ榧導??
class Shape { public: // interface to users of Shapes virtual void draw() const = 0; virtual void rotate(int degrees) = 0; virtual Point center() const = 0; // ... // no data }; class Circle : public Shape { public: void draw() const; void rotate(int) { } Point center() const { return center; } // ... protected: Point cent; Color col; int radius; // ... }; class Triangle : public Shape { public: void draw() const; void rotate(int); Point center() const; // ... protected: Color col; Point a, b, c; // ... };
徽頁?泌惚鳩糞嗤匯乂孔嬬頁勣瓜侭嗤写覚窃?賜宀叙叙叱倖写覚窃?慌峴議?嗽音?壓耽倖写覚窃嶄嶷鹸宸乂旗鷹?椎奕担一?匆挫一?委宸乂孔嬬撃廾撹匯倖窃?泌惚写覚窃勣喘欺宸乂孔嬬?祥斑万壅写覚宸倖窃?
class Shape { public: // interface to users of Shapes virtual void draw() const = 0; virtual void rotate(int degrees) = 0; virtual Point center() const = 0; // ... // no data }; struct Common { Color col; // ... }; class Circle : public Shape, protected Common { public: void draw() const; void rotate(int) { } Point center() const { return center; } // ... protected: Point cent; int radius; }; class Triangle : public Shape, protected Common { public: void draw() const; void rotate(int); Point center() const; // ... protected: Point a, b, c; };
class Empty { }; void f() { Empty a, b; if (&a == &b) cout << "impossible: report error to compiler supplier"; Empty* p1 = new Empty; Empty* p2 = new Empty; if (p1 == p2) cout << "impossible: report error to compiler supplier"; }
struct X : Empty { int a; // ... }; void f(X* p) { void* p1 = p; void* p2 = &p->a; if (p1 == p2) cout << "nice: good optimizer"; }
template<class Scalar> class complex { public: complex() : re(0), im(0) { } complex(Scalar r) : re(r), im(0) { } complex(Scalar r, Scalar i) : re(r), im(i) { } // ... complex& operator+=(const complex& a) { re+=a.re; im+=a.im; return *this; } // ... private: Scalar re, im; };
class Implementer; // forward declaration
class Interface { public: // interface
private: Implementer impl; };
class Implementer {
public:
// implementation details, including data members
総翌?嗤倡痕方議窃嗤倡字崙議蝕?[咎廣?峺贋慧vtable揮栖議腎寂蝕?才宥狛vtable嶄議峺寞寂俊距喘揮栖議扮寂蝕?]?宥械遇冱耽倖斤嵆奐紗議腎寂蝕?頁匯倖忖海。宸倖蝕?辛音弌?遇拝氏夛撹才凪麿囂冱?曳泌C?Fortran?議音惹否來!!嗤倡痕方議窃議坪贋方象下蕉才噸宥議窃頁載音匯劔議。[咎廣?宸嶽坪贋方象下蕉議惹否來諒籾氏公謹囂冱詞栽園殻揮栖醍軍。]
ゞThe Design and Evolution of C++〃 嶄嗤厚謹購噐譜柴尖廷議聾准。
椎担?採扮厘乎斑裂更痕方葎倡椿?填?基宛頁!!輝窃嗤凪万倡痕方議扮昨?低祥哘乎斑裂更痕方葎倡。嗤凪万倡痕方?祥吭龍彭宸倖窃勣瓜写覚?祥吭龍彭万嗤泣^interface ?議龍祇阻。宸劔匯栖?殻會埀祥辛嬬氏參児窃峺寞栖峺?喇万議写覚窃侭糞箭晒遇栖議斤嵆?遇嬬倦宥狛児窃峺寞栖屎械瞥慧宸劔議斤嵆祥勣心裂更痕方頁倦葎倡阻。 箭泌?
class Base { // ... virtual ~Base(); }; class Derived : public Base { // ... ~Derived(); }; void f() { Base* p = new Derived; delete p; // virtual destructor used to ensure that ~Derived is called }
struct F { // interface to object creation functions virtual A* make_an_A() const = 0; virtual B* make_a_B() const = 0; }; void user(const F& fac) { A* p = fac.make_an_A(); // make an A of the appropriate type B* q = fac.make_a_B(); // make a B of the appropriate type // ... } struct FX : F { A* make_an_A() const { return new AX(); } // AX is derived from A B* make_a_B() const { return new BX(); } // BX is derived from B }; struct FY : F { A* make_an_A() const { return new AY(); } // AY is derived from A B* make_a_B() const { return new BY(); } // BY is derived from B }; int main() { user(FX()); // this user makes AXs and BXs user(FY()); // this user makes AYs and BYs // ... }
#include<iostream> using namespace std; class B { public: int f(int i) { cout << "f(int): "; return i+1; } // ... }; class D : public B { public: double f(double d) { cout << "f(double): "; return d+1.3; } // ... }; int main() { D* pd = new D; cout << pd->f(2) << '\n'; cout << pd->f(2.3) << '\n'; }
f(double): 3.3
f(double): 3.6
f(int): 3
f(double): 3.6
算鞘三傍?壓D才B岻寂短嗤嶷墮窟伏。低距喘阻pd->f()?園咎匂祥壓D議兆忖囃戦孀亜孀?孀欺double f(double)朔祥距喘万阻。園咎匂請誼壅欺B議兆忖囃戦肇心心嗤短嗤陳倖痕方厚憲栽勣箔。芝廖?壓C++嶄?短嗤睡囃嶷墮!!写覚窃才児窃埋隼購狼載牌畜?徽匆音嬬撒阻宸訳号裳。峋需ゞThe Design and Evolution of C++〃賜宀ゞThe C++ Programming Language〃及眉井。
音狛?泌惚低掲誼勣睡囃嶷墮?匆音頁短嗤延宥議圭隈!!低祥委椎乂痕方的欺揖匯倖囃戦栖挫阻。聞喘匯倖using蕗苧祥辛參吾協。
class D : public B { public: using B::f; // make every f from B available double f(double d) { cout << "f(double): "; return d+1.3; } // ... };
f(int): 3 f(double): 3.6
#include<string> #include<iostream> using namespace std; class B { public: B(const string& ss) { cout << "B constructor\n"; f(ss); } virtual void f(const string&) { cout << "B::f\n";} }; class D : public B { public: D(const string & ss) :B(ss) { cout << "D constructor\n";} void f(const string& ss) { cout << "D::f\n"; s = ss; } private: string s; }; int main() { D d("Hello"); }
B constructor
B::f
D constructor
廣吭?補竃音頁D::f 。 梢捷窟伏阻焚担?f()頁壓B::B()嶄距喘議。泌惚更夛痕方嶄距喘倡痕方議号夸音頁泌念猟侭峰椎劔?遇頁泌匯乂繁錬李議椎劔肇距喘D::f()。椎担咀葎更夛痕方D::D()賓隆塰佩?忖憲堪s珊隆兜兵晒?侭參輝D::f()編夕繍歌方験公s扮?潤惚謹磯頁!!羨瀧輝字。
裂更夸屎屢郡?恆儉貫写覚窃欺児窃議乏會?介型徨悳誼貫貧吏和介杏???侭參凪距喘倡痕方議佩葎才壓更夛痕方嶄匯劔?倡痕方緩扮緩震瓜鰯協欺陳戦?輝隼哘乎頁児窃晴!!咀葎写覚窃厮将瓜^介 ?阻!!裂更阻???距喘議祥頁陳倖痕方。
厚謹聾准萩需ゞThe Design and Evolution of C++〃?13.2.4.2 賜宀ゞThe C++ Programming Language〃及眉井?15.4.3 。
嗤扮?宸訳号夸瓜盾瞥葎頁喇噐園咎匂議糞恬夛撹議。[咎廣?貫糞恬叔業辛參宸劔盾瞥?壓俯謹園咎匂嶄?岷欺更夛痕方距喘頼穎?vtable嘉瓜秀羨?緩扮倡痕方嘉瓜強蓑鰯協崛写覚窃議揖兆痕方。] 徽並糞貧音頁宸担匯指並!!斑園咎匂糞恬撹^更夛痕方嶄距喘倡痕方匆才貫凪麿痕方嶄距喘匯劔 ?頁載酒汽議[咎廣?峪勣委vtable議秀羨卞崛更夛痕方距喘岻念軸辛]。購囚珊壓噐囂冱譜柴扮議深楚!!斑倡痕方辛參箔廁噐児窃戻工議宥喘旗鷹。[咎廣?枠嗤痔珊頁枠嗤軌?Bjarne糞縞貧頁壓御盆低?音頁^枠嗤糞恬壅嗤号夸 ??遇頁^泌緩糞恬?咀葎号夸泌緩 ?。]
class Arena {
public:
void* allocate(size_t);
void deallocate(void*);
// ...
};
void* operator new(size_t sz, Arena& a)
{
return a.allocate(sz);
}
Arena a1(some arguments);
Arena a2(some arguments);
X* p1 = new(a1) X; Y* p2 = new(a1) Y; Z* p3 = new(a2) Z; // ...
template<class T> void destroy(T* p, Arena& a) { if (p) { p->~T(); // explicit destructor call a.deallocate(p); } }
泌採壓窃写覚悶狼嶄協吶塘斤議operator new() 才 operator delete() 辛參歌心 ゞThe C++ Programming Language〃?Special Edition?15.6准 ?ゞThe Design and Evolution of C++〃?10.4准?參式ゞThe C++ Programming Language〃?Special Edition?19.4.5准。[咎廣?緩侃梓圻猟孚咎。念中嗤戻欺^歌需ゞThe C++ Programming Language〃及眉井 ?議?糞縞貧蒙艶井?Special Edition?才熟除嶷咫議及眉井短焚担曝艶。]
A: 辛參議?徽採駅椿?挫杏?匆俯嗤曾倖尖喇?
泌惚葎阻才^倡痕方距喘 ?傍byebye?椎担鳩糞嗤公窃写覚悶狼^撃競 ?議俶勣。壓譜柴念?音恵枠諒諒徭失?宸乂痕方葎採勣瓜譜柴撹倡議。厘鳩糞需狛宸劔議箭徨?來嬬勣箔秦震議痕方瓜譜柴撹倡議?叙叙咀葎^厘断楼降宸劔恂 ??
挫阻?涙胎泌採?傍阻椎担謹?穎捷低峪頁?岑祇?葎阻蝶嶽栽尖議尖喇?低嬬音嬬契峭艶繁写覚低議窃。基宛頁辛參議。辛炉?宸戦公竃議盾畳岻祇音校孤昌旋鯛。低音誼音壓壓低議^撃競窃 ?嶄倡亭写覚匯倖涙隈更夛議絹廁児窃。珊頁斑箭徨栖御盆厘断匯俳杏?
class Usable;
class Usable_lock {
friend class Usable;
private:
Usable_lock() {}
Usable_lock(const Usable_lock&) {}
};
class Usable : public virtual Usable_lock {
// ...
public:
Usable();
Usable(char*);
// ...
};
Usable a;
class DD : public Usable { };
DD dd; // error: DD::DD() cannot access
// Usable_lock::Usable_lock(): private member
斑厘断栖心宸粁旗鷹?
template<class Container> void draw_all(Container& c) { for_each(c.begin(),c.end(),mem_fun(&Shape::draw)); }
葎阻壼泣俺彌欺宸倖危列?厘断辛參宸劔亟旗鷹?
template<class Container> void draw_all(Container& c) { Shape* p = c.front(); // accept only containers of Shape*s for_each(c.begin(),c.end(),mem_fun(&Shape::draw)); }
template<class Container> void draw_all(Container& c) { typedef typename Container::value_type T; Can_copy<T,Shape*>(); // accept containers of only Shape*s for_each(c.begin(),c.end(),mem_fun(&Shape::draw)); }
template<class T1, class T2> struct Can_copy { static void constraints(T1 a, T2 b) { T2 c = a; b = a; } Can_copy() { void(*p)(T1,T2) = constraints; } };
屡隼泌緩?厘断孤宅音孤巌壓C++囂冱云附嶄協吶窃貌Can_copy()賜宀厚單囘酒準議囂隈椿?The Design and Evolution of C++蛍裂阻緩恂隈揮栖議是佃。厮将嗤俯俯謹謹譜柴尖廷検竃邦中?峪葎阻斑根constraints議庁医窃叟噐廱亟?揖扮珊勣斑園咎匂壓constraints音瓜諾怎扮公竃否叟尖盾議竃危嶧連。曳圭傍?厘壓Can_copy嶄^聞喘痕方峺寞 ?議譜柴祥栖徭噐Alex Stepanov才Jeremy Siek。厘範葎厘議Can_copy()糞恬珊音欺辛參炎彈晒議殻業!!万俶勣厚謹糞樹議殊刮。総翌?C++聞喘宀氏壟囑俯謹音揖窃侏議constraints?朕念心栖珊短嗤陳嶽侘塀議揮constraints議庁医資誼儿宜謹方議屶隔。
厮嗤音富購噐constraints議^坪崔囂冱屶隔 ?圭宛瓜戻咏才糞恬。徽凪糞勣燕峰constraint功云音俶勣焚担呟窄儖械議叫廉?穎捷?輝厘断亟匯倖庁医扮?厘断啜嗤C++揮公厘断議膿嗤薦議燕器嬬薦。斑旗鷹栖葎厘議三恬屬杏?
template<class T, class B> struct Derived_from { static void constraints(T* p) { B* pb = p; } Derived_from() { void(*p)(T*) = constraints; } }; template<class T1, class T2> struct Can_copy { static void constraints(T1 a, T2 b) { T2 c = a; b = a; } Can_copy() { void(*p)(T1,T2) = constraints; } }; template<class T1, class T2 = T1> struct Can_compare { static void constraints(T1 a, T2 b) { a==b; a!=b; a<b; } Can_compare() { void(*p)(T1,T2) = constraints; } }; template<class T1, class T2, class T3 = T1> struct Can_multiply { static void constraints(T1 a, T2 b, T3 c) { c = a*b; } Can_multiply() { void(*p)(T1,T2,T3) = constraints; } }; struct B { }; struct D : B { }; struct DD : D { }; struct X { }; int main() { Derived_from<D,B>(); Derived_from<DD,B>(); Derived_from<X,B>(); Derived_from<int,B>(); Derived_from<X,int>(); Can_compare<int,float>(); Can_compare<X,B>(); Can_multiply<int,float>(); Can_multiply<int,float,double>(); Can_multiply<B,X>(); Can_copy<D*,B*>(); Can_copy<D,B*>(); Can_copy<int,B*>(); } // the classical "elements must derived from Mybase*" constraint: template<class T> class Container : Derived_from<T,Mybase> { // ... };
qsort(array,asize,sizeof(elem),elem_compare);
sort(vec.begin(),vec.end());
struct Record { string name; // ... }; struct name_compare { // compare Records using "name" as the key bool operator()(const Record& a, const Record& b) const { return a.name<b.name; } }; void f(vector<Record>& vs) { sort(vs.begin(), vs.end(), name_compare()); // ... }
総翌?珊嗤俯謹繁仞浜sort()議窃侏芦畠來!!勣聞喘万辛音俶勣販採膿崙議窃侏廬算。斤噐炎彈窃侏?匆音駅亟compare()痕方?福並音富。泌惚?心厚峋勝議盾瞥?歌心厘議ゞLearning Standard C++ as a New Language〃匯猟。
総翌?葎採sort()勣曳qsort()酔?咀葎万厚挫仇旋喘阻C++議坪選囂隈囂吶。
Function object議梱吶曳宥械吭吶貧議痕方厚鴻刑?咀葎万辛參壓謹肝距喘岻寂隠隔蝶嶽^彜蓑 ?!!宸才床蓑蕉何延楚嗤呟爆揖垢岻虫?音狛宸嶽^彜蓑 ?珊辛參瓜兜兵晒?珊辛參貫翌中栖殊霞?宸辛勣曳床蓑蕉何延楚膿阻。厘断栖心匯倖箭徨?
class Sum { int val; public: Sum(int i) :val(i) { } operator int() const { return val; } // extract value int operator()(int i) { return val+=i; } // application }; void f(vectorv) { Sum s = 0; // initial value 0 s = for_each(v.begin(), v.end(), s); // gather the sum of all elements cout << "the sum is " << s << "\n"; // or even: cout << "the sum is " << for_each(v.begin(), v.end(), Sum(0)) << "\n"; }
壓炎彈垂嶄function objects瓜鴻刑聞喘?宸公炎彈垂揮栖阻自寄議痩試來才辛制婢來。
[咎廣?C++頁匯倖鴬寡巉海議囂冱?function object議古廷祥頁貫functional programming嶄処栖議?遇C++云附議膿寄才燕孖薦議戟源匆聞宸嶽^鎮栖麼吶 ?撹葎辛嬬。匯違遇冱?壓聞喘function object議仇圭匆械辛參聞喘痕方峺寞?壓厘断珊音母呂function object議扮昨厘断匆械械頁聞喘峺寞議。徽協吶匯倖痕方峺寞議囂隈辛音頁湊酒汽苧阻?遇拝壓C++嶄峺寞壼厮嘘貧阻^危列岻坿 ?議具兆。厚採趨?宥狛峺寞距喘痕方奐紗阻寂俊蝕?。侭參?涙胎葎阻囂隈議單胆珊頁丼楕議戻互?脅哘乎戻開聞喘function objects。
和中厘断壅貫譜柴庁塀議叔業栖厚侮秘仇尖盾function objects?宸頁Visitor庁塀議灸侏哘喘。輝厘断勣斤蝶倖/蝶乂斤嵆仏紗蝶嶽荷恬?徽嗽音?繍宸嶽荷恬尫協棒?椎担祥辛參寡喘Visitor庁塀。壓Design Patterns匯慕嶄?恬宀委宸嶽庁塀糞恬葎?宥狛匯倖Visitor窃栖戻工宸嶽荷恬?壓念中Bjarne Stroustrup議旗鷹嶄?Sum祥頁匯倖Visitor議延悶??喘Visitor窃糞箭晒匯倖visitor斤嵆?輝隼?壓念中議旗鷹嶄斤哘議頁s??隼朔壓Iterator議亨旗狛殻嶄?葎耽匯倖斤嵆距喘visitor.visit()。宸戦visit()頁Visitor窃議匯倖撹埀痕方?恬喘屢輝噐Sum窃嶄椎倖^蒙歩議撹埀痕方 ?!!operator()?visit()匆頼畠辛參瓜協吶葎坪選痕方?參肇茅寂俊來?戻互來嬬。壓緩戻萩響宀廣吭?C++委嶷墮議荷恬憲匆心恬痕方?峪音狛頁醤嗤蒙歩痕方兆議痕方。侭參糞縞貧Design Patterns匯慕嶄Visitor庁塀議幣袈糞恬才宸戦function object議糞恬寄悶貧頁吉勺議。匯倖function object匆祥頁匯倖蒙歩議Visitor。]
#include<vector> #include<string> #include<iostream> #include<algorithm> using namespace std; int main() // small program messing around with strings { cout << "enter some whitespace-separated words:\n"; vector<string> v; string s; while (cin>>s) v.push_back(s); sort(v.begin(),v.end()); string cat; typedef vector<string>::const_iterator Iter; for (Iter p = v.begin(); p!=v.end(); ++p) cat += *p+"+"; cout << cat << '\n'; }
萩廣吭宸戦短嗤?塋週陳擺羚楡躊翮襦C屍从蝪c屍仞猥要Ĺ撮c屍侑膤欛豌癸c屍佛訊撞調麸]渣藤r加屍儘胡襦H膵蘘荒?function object才炎彈麻隈[咎廣?峺炎彈垂嶄戻工議刑侏麻隈]?厘銭Iterator匆辛參音喘。音狛宸穎捷峪頁匯倖弌殻會?姫痔冑喘釘偽?
輝隼?宸乂圭隈匆旺掲涙亳辛似?遇拝傍軟栖否叟恂軟栖佃?勣狼由仇聞喘万断匆旺音悳頁載酒汽。音狛?涙胎泌採?万断議鴻刑癖喘來綜繁妾冏?遇拝宥狛卞肇寄楚議?塋縦擺羞崚?/瞥慧旗鷹?万断鳩糞奐膿阻旗鷹議辛響來才辛砿尖來。壼壓1981定?厘祥峺竃宥狛寄嫌業受富俶勣?塋充嘔垤楡躓超塹麒鎣殖j荒?C++^繍並秤恂斤 ?繍音壅頁匯周自凪継舞議取賞販暦。
泌惚低議哘喘糟囃短嗤嬬壓坪贋砿尖圭中廁低匯越岻薦議窃垂?椎担泌惚低珊?斑低議罷周蝕窟延誼屡酔楯嗽嬬煤防誼欺屎鳩潤惚?恷挫頁枠秀羨宸劔匯倖垂。
泌惚低涙隈斑坪贋蛍塘才瞥慧撹葎斤嵆議^徭隼佩葎 ??椎担崛富低辛參宥狛聞喘彿坿鞘凹栖勝楚閲窒坪贋亶息。宸戦頁匯倖幣箭?邪譜低俶勣貫痕方卦指匯倖斤嵆?宸倖斤嵆頁壓徭喇坪贋均貧蛍塘議?低辛嬬氏梨芝瞥慧椎倖斤嵆!!穎捷厘断涙隈宥狛殊臥峺寞栖鳩協凪峺?議斤嵆頁倦俶勣瓜瞥慧?厘断匆涙隈誼岑豊哘乎減夭瞥慧万。椎担?祥喘彿坿鞘凹杏。曳泌?炎彈垂嶄議auto_ptr祥辛參逸廁確賠?^瞥慧斤嵆 ?夭販梢捷壓豊。厘断栖心?
#include<memory> #include<iostream> using namespace std; struct S { S() { cout << "make an S\n"; } ~S() { cout << "destroy an S\n"; } S(const S&) { cout << "copy initialize an S\n"; } S& operator=(const S&) { cout << "copy assign an S\n"; } }; S* f() { return new S; // who is responsible for deleting this S? }; auto_ptr<S> g() { return auto_ptr<S>(new S); // explicitly transfer responsibility for deleting this S } int main() { cout << "start main\n"; S* p = f(); cout << "after f() before g()\n"; // S* q = g(); // caught by compiler auto_ptr<S> q = g(); cout << "exit main\n"; // leaks *p // implicitly deletes *q }
宸戦峪頁坪贋彿坿砿尖議箭徨?崛噐凪万窃侏議彿坿砿尖?辛參泌隈土崙。
泌惚壓低議蝕窟桟廠嶄涙隈狼由仇聞喘宸嶽圭隈?曳圭傍?低聞喘阻及眉圭戻工議硬境旗鷹?賜宀垓硬^僭肖繁 ?歌嚥阻低議?朕蝕窟??椎担低壓蝕窟狛殻嶄辛認嵐勣芝廖聞喘坪贋契息殊霞殻會?賜宀孤巌聞喘征侍辺鹿匂?Garbage Collector?。
狹?貫呟械侃尖旗鷹卦指欺呟械砺竃侃写偬峇佩朔中議旗鷹議?隈載挫[咎廣?孖佩呟械字崙議譜柴頁?輝呟械瓜砺竃才侃尖朔?貫侃尖旗鷹侭壓議椎倖catch翠吏和峇佩]?徽麼勣諒籾壓噐!!exception handler音辛嬬岑祇葎阻斑朔中議旗鷹屎械塰佩?俶勣恂謹富賠茅呟械議垢恬[咎廣?穎捷?輝嗤呟械窟伏?並秤祥嗤泣音湊斤匠阻?音頁宅?厚採趨辺憤醒妙徨喟垓頁周醍軍議並]?侭參?泌惚勣斑^写偬峇佩 ?嬬校屎械垢恬?亟throw旗鷹議繁才亟catch旗鷹議繁駅倬斤泳緩議旗鷹脅載母呂?遇宸祥揮栖阻鹸墫議屢札卆正購狼[咎廣?屡峺蝕窟繁埀岻寂議^屢札卆正 ??匆峺旗鷹寂議屢札卆正!!諸骼栽議旗鷹辛音頁挫旗鷹填 :O) ]?氏揮栖載謹醍軍議略擦諒籾。
壓厘譜柴C++議呟械侃尖字崙議扮昨?厘奚範寔仇深打狛宸倖諒籾?壓C++炎彈晒議狛殻嶄?宸倖諒籾匆瓜峋聾仇網胎狛。?歌需ゞThe Design and Evolution of C++〃嶄購噐呟械侃尖議嫗准?泌惚低?編編心壓砺竃呟械岻念嬬音嬬盾畳諒籾隼朔写偬吏和峇佩?低辛參枠距喘匯倖^殊臥!志鹸 ?痕方?隼朔?泌惚珊頁音嬬盾畳諒籾?壅委呟械砺竃。匯倖宸劔議箭徨頁new_handler。
壓C++嶄?侃尖坪贋嶷蛍塘議熟挫一隈頁聞喘炎彈垂嶄議否匂?曳泌vector。[咎廣?宸乂否匂氏徭失砿尖俶勣議坪贋?壓駅勣扮氏^奐海樫雁 ?!!序佩嶷蛍塘。]
#include<iostream> #include<string> using namespace std; int main() { cout << "Please enter a word:\n"; string s; cin>>s; cout << "You entered " << s << '\n'; }
泌惚低俶勣匯肝響匯屁佩?辛參宸劔?
#include<iostream> #include<string> using namespace std; int main() { cout << "Please enter a line:\n"; string s; getline(cin, s); cout << "You entered " << s << '\n'; }
class File_handle { FILE* p; public: File_handle(const char* n, const char* a) { p = fopen(n,a); if (p==0) throw Open_error(errno); } File_handle(FILE* pp) { p = pp; if (p==0) throw Open_error(errno); } ~File_handle() { fclose(p); } operator FILE*() { return p; } // ... }; void f(const char* fn) { File_handle f(fn,"rw"); // open fn for reading and writing // use file through f }
総翌?萩心心ゞThe C++ Programming Language〃現村E嶄議彿坿砿尖箭徨。
#include<memory> using namespace std; struct X { int m; // .. }; void f() { auto_ptr<X> p(new X); X* q = new X; p->m++; // use p just like a pointer q->m++; // ... delete q; }
泌惚壓旗鷹喘// ...炎廣議仇圭砺竃呟械?椎担p氏瓜屎械評茅!!宸倖孔斥哘乎芝壓auto_ptr議裂更痕方遊貧。音狛?q峺?議X窃侏斤嵆祥短嗤瓜瞥慧?咀葎音頁喘auto_ptr協吶議?。峋秤萩需ゞThe C++ Programming Language〃14.4.2准。
Auto_ptr頁匯倖煤楚雫議窃?短嗤哈秘哈喘柴方字崙。泌惚低委匯倖auto_ptr?曳泌?ap1?験公総匯倖auto_ptr?曳泌?ap2??椎担ap2繍隔嗤糞縞峺寞?遇ap1繍隔嗤巣峺寞。箭泌?
#include<memory> #include<iostream> using namespace std; struct X { int m; // .. }; int main() { auto_ptr<X> p(new X); auto_ptr<X> q(p); cout << "p " << p.get() << " q " << q.get() << "\n"; }
p 0x0 q 0x378d0
宸戦?囂吶貌窄頁^廬卞 ??遇掲^申唄 ??宸賜俯嗤泣綜繁妾冏。蒙艶勣廣吭議頁?音勣委auto_ptr恬葎炎彈否匂議歌方!!炎彈否匂勣箔宥械議申唄囂吶。箭泌?
std::vector<auto_ptr<X> >v; // error
匯倖auto_ptr峪嬬隔嗤峺?汽倖圷殆議峺寞?遇音頁方怏峺寞?
void f(int n) { auto_ptr<X> p(new X[n]); // error // ... }
椎担?心栖厘断哘乎喘匯倖聞喘delete[]栖瞥慧峺寞議?出auto_array議窃貌叫叫栖慧方怏阻?填?音?音?短嗤焚担auto_array。尖喇頁?音俶勣嗤亜!!厘断頼畠辛參喘vector啄?
void f(int n) { vector<X> v(n); // ... }
音辛參!!貫低涙隈delete匯倖參malloc()蛍塘遇栖岻斤嵆議吭吶貧遇冱。低匆涙隈free()賜realloc()匯倖喇new蛍塘遇栖議斤嵆。
C++議new才delete塰麻憲鳩隠更夛才裂更屎械窟伏?徽C欠鯉議malloc()、calloc()、free()才realloc()辛音隠屬宸泣。遇拝?短嗤販採繁嬬?低毅隠?new/delete才malloc/free侭嫺陣議坪贋頁屢札^惹否 ?議。泌惚壓低議旗鷹嶄?曾嶽欠鯉詞喘遇短嗤公低夛撹醍軍?椎厘峪嬬傍?岷欺朕念葎峭?低頁掲械侑塰議 :O)
泌惚低咀葎房廷^胆挫議析realloc() ??俯謹繁脅房廷慢?遇涙隈護普屁倖硬析議C坪贋蛍塘字崙?握塁式鱗???椎担深打聞喘炎彈垂嶄議vector杏。箭泌?
// read words from input into a vector of strings: vector<string> words; string s; while (cin>>s && s!=".") words.push_back(s);
厘議ゞLearning Standard C++ as a New Language〃匯猟嶄公竃阻凪万箭徨?辛參歌深。
A: 壓C嶄?低辛參咨塀廬算?徽宸頁音芦畠議?箭泌?
#include<stdio.h> int main() { char i = 0; char j = 0; char* p = &i; void* q = p; int* pp = q; /* unsafe, legal C, not C++ */ printf("%d %d\n",i,j); *pp = -1; /* overwrite memory starting at &i */ printf("%d %d\n",i,j); }
int* pp = (int*)q;
int* pp = static_cast<int*>(q);
壓C嶄匯窃恷械需議音芦畠算侏窟伏壓繍malloc()蛍塘遇栖議坪贋験公蝶倖峺寞岻扮?箭泌?
int* p = malloc(sizeof(int));
int* p = new int;
typedef std::complex<double> cmplx; /* C style: */ cmplx* p = (cmplx*)malloc(sizeof(int)); /* error: wrong size */ /* forgot to test for p==0 */ if (*p == 7) { /* ... */ } /* oops: forgot to initialize *p */ // C++ style: cmplx* q = new cmplx(1,2); // will throw bad_alloc if memory is exhausted if (*q == 7) { /* ... */ }
Q: 泌惚低?誼欺匯倖辛喘噐械楚燕器塀嶄議械楚?箭泌方怏寄弌議協吶?椎担低嗤曾嶽僉夲?
class X { static const int c1 = 7; enum { c2 = 19 }; char v1[c1]; char v2[c2]; // ... };
匯凛李肇?c1議協吶貌窄厚紗岷舜阻輝?徽艶梨阻峪嗤static議屁侏賜旦訟侏楚嘉嬬泌緩兜兵晒。宸祥載嗤蕉尫來?箭泌?
class Y { const int c3 = 7; // error: not static static int c4 = 7; // error: not const static const float c5 = 7; // error not integral };
厘珊頁厚浪散螺^enum老隈 ??咀葎宸嶽協吶辛卞峅來挫?遇拝音氏哈嗾厘肇聞喘掲炎彈議^窃坪兜兵晒 ?制婢囂隈。
椎担?葎採勣嗤宸乂音圭宴議尫崙?咀葎窃宥械蕗苧壓遊猟周嶄?遇遊猟周吏吏瓜俯謹汽圷侭淫根。[侭參?窃辛嬬氏瓜嶷鹸蕗苧。]徽頁?葎阻閲窒全俊匂譜柴議鹸墫晒?C++勣箔耽倖斤嵆脅峪嬬瓜協吶匯肝。泌惚C++塋俯窃坪協吶勣恬葎斤嵆瓜贋壓坪贋嶄議糞悶?椎担宸?勣箔祥涙隈諾怎阻。購噐C++譜柴扮議匯乂孵嶬?歌需ゞThe Design and Evolution of C++〃。
泌惚宸倖械楚音俶勣瓜喘噐械楚燕器塀?椎担低議僉夲噫仇祥曳熟寄阻?
class Z { static char* p; // initialize in definition const int i; // initialize in constructor public: Z(int ii) :i(ii) { } }; char* Z::p = "hello, there";
class AE { // ... public: static const int c6 = 7; static const int c7 = 31; }; const int AE::c7; // definition int f() { const int* p1 = &AE::c6; // error: c6 not an lvalue const int* p2 = &AE::c7; // ok // ... }
delete p; // ... delete p;
填?音音?宸倖麼吭音校^挫 ?。匯倖尖喇頁?瓜delete議峺寞隆駅頁恣峙。厘断栖心?
delete p+1; delete f(x);
T* p = new T; T* q = p; delete p; delete q; // ouch!
泌惚低状誼瞥慧坪贋扮委峺寞崔巣載嶷勣?椎担音形亟宸劔匯倖destroy痕方?
template<class T> inline void destroy(T*& p) { delete p; p = 0; }
音形委delete揮栖議醍軍心恬^勝楚富喘new/delete?謹喘炎彈垂嶄議否匂 ?岻総匯訳尖喇杏 :O)
萩廣吭?委峺寞恬葎哈喘勧弓?參宴delete辛參委峺寞崔巣?氏揮栖駆翌議丼吩!!契峭嘔峙瓜勧弓公destroy() ?
int* f(); int* p; // ... destroy(f()); // error: trying to pass an rvalue by non-const reference destroy(p+1); // error: trying to pass an rvalue by non-const reference
void main() { /* ... */ }
int main() { /* ... */ }
int main(int argc, char* argv[]) { /* ... */ }
#include<iostream> int main() { std::cout << "This program returns the integer value 0\n"; }
#include<iostream> main() { /* ... */ }
遇^sizeof ?涙隈瓜嶷墮頁咀葎音富坪何荷恬?曳泌峺寞紗隈?脅卆正噐万?箭泌?
X a[10]; X* p = &a[3]; X* q = &a[3]; p++; // p points to a[4] // thus the integer value of p must be // sizeof(X) larger than the integer value of q
壓N::m嶄?N才m脅音頁燕器塀?万断峪頁園咎匂^範紛 ?議兆忖?^:: ?峇佩議糞縞荷恬頁園咎扮議兆忖囃盾裂?旺短嗤燕器塀議塰麻韮膚壓坪。賜俯嗤繁氏状誼嶷墮匯倖^x::y ??凪嶄x頁糞縞斤嵆?遇掲兆忖囃賜窃兆?頁匯倖挫麼吭?徽宸劔恂哈秘阻仟議囂隈[咎廣?嶷墮議云吭頁斑荷恬憲辛參嗤仟議囂吶?遇音頁厚個囂隈!!倦夸氏哈軟詞岱]?厘辛音範葎仟囂隈揮栖議鹸墫來氏公厘断焚担挫侃。
圻夸貧栖傍?^. ?塰麻憲頁辛參瓜嶷墮議?祥崧^-> ?匯劔。音狛?宸氏揮栖囂吶議詞巋!!厘断欺久頁?才^. ?朔中議斤嵆嬉住祇椿?珊頁^. ?朔中議叫叫侭糞縞峺?議糞悶嬉住祇椿?心心宸倖箭徨?万邪譜^. ?嶷墮頁辛參議??
class Y { public: void f(); // ... }; class X { // assume that you can overload . Y* p; Y& operator.() { return *p; } void f(); // ... }; void g(X& x) { x.f(); // X::f or Y::f or error? }
宸倖諒籾嗤挫叱嶽盾畳圭宛。壓C++炎彈晒岻扮?採嶽圭宛葎煮旺音苧?圈O現敘覯亮菑?The Design and Evolution of C++〃。
#include<iostream> #include<string> #include<sstream> using namespace std; string itos(int i) // convert int to string { stringstream s; s << i; return s.str(); } int main() { int i = 127; string ss = itos(i); const char* p = ss.c_str(); cout << ss << " " << p << "\n"; }
音狛泌惚斑繁栖響?曾宀議根吶祥嗤侭音揖阻。旗鷹議慕亟欠鯉頁載嶷勣議。C欠鯉議燕器塀才蕗苧塀械瓜心恬曳^necessary evil ?[咎廣?^駅勣岻具 ??吭峺葎阻器欺蝶嶽朕議遇音誼音原竃議旗勺。箭泌嗤繁範葎桟廠議篤撒頁将蔀窟婢揮栖議^necessary evil ?]厚壯議叫廉?遇C++夸載膿距窃侏。侭參?^int *p ?才^int* p ?岻寂旺涙斤危岻蛍?峪嗤欠鯉岻尸。
匯倖灸侏議C殻會埀氏亟^int *p ??遇拝尅尅嗤簡仇御盆低^宸燕幣`*p頁匯倖int ? ?!!油貧肇勇嗤祇尖議。宸戦?*才p鰯壓阻匯軟!!宸祥頁C議欠鯉。宸嶽欠鯉膿距議頁囂隈。
遇匯倖灸侏議C++殻會埀氏亟^int* p ??旺御盆低^p頁匯倖峺?int議峺寞?p議窃侏頁int* ?。宸嶽欠鯉膿距議頁窃侏。輝隼?厘浪散宸嶽欠鯉 :O) 遇拝?厘範葎?窃侏頁掲械嶷勣議古廷?厘断哘乎廣嶷窃侏。万議嶷勣來某坐音冉噐C++囂冱嶄議凪万^熟葎互雫議何蛍 ?。[咎廣?幗泌RTTI?光嶽cast?template字崙吉?辛各葎^熟互雫議何蛍 ?阻杏?徽万断凪糞匆頁窃侏古廷議制婢才塰喘。厘奚亟狛曾鐙霧欺C++才OOP議猟嫗窟燕壓云侵貧?猟嶄脅膿距阻尖盾^窃侏 ?岻嶷勣來。厘珊奚咎狛Object Unencapsulated ?宸云慕喇恬宀枠念侭广壓利貧鴻葎送勧議C++?? A Critique俐匡遇栖?嶄讐窃侏議嫗准?宸云慕議恬宀封崛各Object Oriented Programming哘乎屎兆葎Type Oriented Programming!!^中?窃侏園殻 ??宸嗤泣獣覧狛屎阻?徽窃侏鳩頁園殻囂冱岻宰伉何蛍。]
輝蕗苧汽倖延楚扮?int *才int*議餓艶旺音頁蒙艶融竃?徽輝厘断勣匯肝蕗苧謹倖延楚扮?叟詞巋岻侃祥畠羽其竃栖阻?
int* p, p1; // probable error: p1 is not an int*
int *p, p1; // probable error?
int* p = &i; int p1 = p; // error: int initialized by int*
耽輝器欺蝶嶽朕議嗤曾訳參貧余抄?祥氏嗤乂繁瓜吾冊与?耽輝匯乂僉夲頁竃噐倖繁浪挫?尸胎祥氏涙俚涙峭。釈隔匯肝峪蕗苧匯倖峺寞旺壓蕗苧扮乏宴兜兵晒?是氾厘断厮消議詞巋岻坿祥氏昧欠陛肇。泌惚低?阻盾嗤購C議蕗苧囂隈議厚謹網胎?歌需ゞThe Design and Evolution of C++〃 。
厘倖繁浪散聞喘^K&R ?欠鯉?泌惚麻貧椎乂C囂冱嶄音贋壓議更夛岻聞喘降箭?椎担繁断嗤扮匆各岻葎^Stroustrup ?欠鯉。箭泌?
class C : public B { public: // ... }; void f(int* p, int max) { if (p) { // ... } for (int i = 0; i<max; ++i) { // ... } }
屎鳩議抹序掲械嶷勣。
匯乂譜柴諒籾?曳泌聞喘渇嵆窃栖燕幣嶷勣議順中、聞喘庁医栖燕幣痩試遇辛制婢議窃侏芦畠渇嵆、屎鳩聞喘^呟械 ?栖燕幣危列?垓垓勣曳旗鷹欠鯉嶷勣。
[咎廣?ゞThe Practice of Programming〃嶄嗤匯嫗斤^旗鷹欠鯉 ?諒籾恬阻峋聾議懐峰。]
const int a = 1; // ok int const b = 2; // also ok
葎焚担氏宸劔?輝厘窟苧^const ??恷壼頁瓜凋兆葎^readonly ?拝嗤匯倖出^writeonly ?議斤哘麗?扮?厘斑万壓念中才朔中脅佩?咀葎宸音氏揮栖屈吶來。輝扮議C/C++園咎匂斤俐蔑憲載富嗤膿紗議囂會号夸。
厘音芝誼輝扮嗤狛焚担購噐囂會議侮房母打賜屢購議尸胎。匯乂壼豚議C++聞喘宀?蒙艶頁厘?輝扮峪頁汽歓仇状誼const int c = 10;勣曳int const c = 10;挫心遇厮。賜俯?厘頁鞭阻宸周並糞議唹峒?俯謹厘壼定亟議箭徨頁喘^readonly ?俐蔑議?遇readonly int c = 10;鳩糞心貧肇勣曳int readonly c = 10;穂捲。遇恷壼議聞喘^const ?議C/C++旗鷹頁厘喘畠蕉臥孀紋算孔嬬委readonly算撹const遇栖議。厘珊芝誼才叱倖繁網胎狛購噐囂隈^延悶 ?諒籾?淫凄Dennis Ritchie。音狛厘音芝誼輝扮厘断霧議頁陳叱嶽囂冱阻。
総翌?萩廣吭?泌惚峺寞云附音辛瓜俐個?椎担const哘乎慧壓^* ?議朔中。箭泌?
int *const p1 = q; // constant pointer to int variable int const* p2 = q; // pointer to constant int const int* p3 = q; // pointer to constant int
#include "someheader.h"
struct S {
int alpha;
int beta;
};
泌惚嗤繁(音苧崘仇)亟阻匯倖出^alpha ?賜宀^beta ?議崎?椎担宸粁旗鷹涙隈宥狛園咎?封崛辛嬬厚壯!!園咎竃匯乂低隆奚圓創議潤惚。曳圭傍?泌惚^someheader.h ?淫根阻泌和協吶?
#define alpha 'a' #define beta b[2]
椎担念中議旗鷹祥頼畠嘘宣云吭阻。
音侑議頁?低涙隈鳩隠凪麿殻會埀音係低侭範葎議^嘲汗議 ?危列。曳圭傍?除栖嗤繁御盆厘?麿断囑欺匯倖根^goto ?囂鞘議崎。厘需欺狛宸劔議旗鷹?匆油欺狛宸劔議胎泣!!嗤扮崎嶄議^goto ?頁嗤喘議。箭泌?
#define prefix get_ready(); int ret__ #define Return(i) ret__=i; do_something(); goto exit #define suffix exit: cleanup(); return ret__ void f() { prefix; // ... Return(10); // ... Return(x++); //... suffix; }
匯倖械需遇裏虫議諒籾頁?痕方欠鯉議崎音恆便痕方歌方距喘号夸。箭泌?
#define square(x) (x*x) void f(double d, int i) { square(d); // fine square(i++); // ouch: means (i++*i++) square(d+1); // ouch: means (d+1*d+1); that is, (d+d+1) // ... }
#define square(x) ((x)*(x)) /* better */
厘岑祇嗤乂?凪万囂冱嶄?瓜各葎^崎 ?議叫廉旺音嵆C/C++圓侃尖匂侭侃尖議^崎 ?椎劔髪尣謹謹、醍軍嶷嶷?徽厘旺音?個序C++議崎?遇頁秀咏低屎鳩聞喘C++囂冱嶄議凪麿字崙?曳泌坪選痕方、庁医、更夛痕方、裂更痕方、呟械侃尖吉。