Si të konfiguroni telefonat inteligjentë dhe PC. Portali informativ

Përdorimi efektiv c 55 mënyra të drejta.

Emri: Përfitoni sa më shumë nga C++ - 35 këshilla të reja për të përmirësuar programet dhe projektet tuaja.

Libri, i cili është një vazhdim i edicionit popullor të Efektive C ++, mund të mësoni se si të përdorni në mënyrë më efektive konstruktet e gjuhës C ++, si dhe të konsideroni se si të shkruani cast, zbatimin e mekanizmit RTTI, mbingarkimin e operatorit rregullat, etj. Libri ofron rekomandime për përdorimin e treguesve inteligjentë, konstruktorëve virtualë, operatorit të ri të buferuar, klasave proxy dhe dërgimit të dyfishtë. Vëmendje e veçantë i kushtohet punës me përjashtime dhe mundësisë së përdorimit të kodit C në programet e shkruara në C ++. Karakteristikat më të fundit të gjuhës janë të përshkruara në detaje dhe është paraqitur mënyra e përdorimit të tyre për të rritur performancën e programeve. Aplikacionet ruajnë kodin për shabllonin auto_ptr dhe një listë të shënimeve të literaturës C++ dhe burimeve të internetit.


përmbajtja
Prezantimi. katërmbëdhjetë
Kapitulli 1. Bazat. 23
Rregulli 1. Dalloni midis treguesve dhe referencave. 23
Rregulli 2: Preferoni hedhjen e tipit C++. 25
Rregulli 3. Asnjëherë mos përdorni polimorfizëm në vargje. tridhjetë
Rregulli 4: Shmangni konstruktorët e papërshtatshëm të paracaktuar. 33
Kapitulli 2 Operatorët. 38
Rregulli 5: Kujdes nga funksionet e konvertimit të tipit të përcaktuar nga përdoruesi. 38
Rregulli 6. Dalloni midis formave parashtesore dhe pasfiksore të operatorëve të rritjes dhe zvogëlimit. 45
Rregulli 7: Mos i mbingarkoni kurrë operatorët &&, 11 dhe. 48
Rregulli 8. Dalloni mes kuptimit të operatorëve new dhe delete. 51
Kapitulli 3 Përjashtimet. 57
Rregulli 9: Përdorni destruktorë për të shmangur rrjedhjet e burimeve. 58
Rregulli 10 Mos lëshoni burime te konstruktorët. 63
Rregulli 11 Mos e zgjeroni trajtimin e përjashtimeve jashtë destruktorit. 71
Rregulli 12. Dalloni hedhjen e një përjashtimi nga kalimi i një parametri ose thirrja e një funksioni virtual. 73
Pika 13: Kapja e përjashtimeve të referencës së kaluar. 80
Rregulli 14: Përdorni specifikimet e përjashtimeve me mençuri. 84
Rregulli 15. Vlerësoni koston e trajtimit të përjashtimeve. 90
Kapitulli 4 Efikasiteti. 94
Rregulli 16 Mos harroni rregullin 80-20. 95
Rregulli 17: Përdorni vlerësimin dembel. 97
Rregulli 18: Ulni koston e llogaritjeve të pritshme. 106
Rregulli 19. Shqyrtoni shkaqet e objekteve të përkohshme. 110
Pika 20: Bëni të lehtë optimizimin e vlerës së kthimit. 113
Pika 21: Përdorni mbingarkimin për të shmangur konvertimin e nënkuptuar të llojit. 116
Rregulli 22. Kurdoherë që është e mundur, përdorni një operator caktimi në vend të një operatori të vetëm. 118
Rregulli 23. Përdorni biblioteka të ndryshme. 121
Pika 24 Merrni parasysh kostot që lidhen me funksionet virtuale, trashëgiminë e shumëfishtë, klasat bazë virtuale dhe RTTI. 124
Kapitulli 5 Pritje. 134
Rregulla 25. Bëni konstruktorë dhe funksione që nuk janë anëtarë të klasës virtuale. 134
Rregulli 26: Kufizoni numrin e objekteve në një klasë. 140
Pika 27: Kërkoni ose mos lejoni objektet në grumbull, në varësi të situatës. 154
Pika 28: Përdorni tregues të zgjuar. 167
Rregulli 29 Përdorni numërimin e referencës. 190
Rregulli 30 Përdorni klasa proxy. 218
Rregulli 31: Bëni funksionet virtuale për më shumë se një objekt. 231
Kapitulli 6 Të ndryshme. 254
Rregulli 32 Programi me një sy nga e ardhmja. 254
Rregulli 33. Bëni klasat jo-terminale abstrakte. 259
Rregulli 34. Di të përdorësh një program uji C dhe C++. 270
Rregulli 35. Njihuni me standardin e gjuhës. 276
Aneksi 1. Lista e literaturës së rekomanduar. 284
Shtojca 2. Zbatimi i shabllonit auto_ptr.

Operatorët.
Operatorët e mbingarkuar duhet të trajtohen me respekt. Ato ju lejojnë të përdorni të njëjtën sintaksë për llojet e përcaktuara nga përdoruesi si për llojet e integruara, dhe gjithashtu ofrojnë perspektiva të padëgjuara falë funksionalitetit pas këtyre operatorëve. Por të qenit në gjendje të bëni karaktere si + ose - të bëjnë çdo gjë do të thotë gjithashtu që operatorët e mbingarkuar mund t'i bëjnë programet plotësisht konfuze. Megjithatë, ka shumë programues të aftë të C++ që dinë të përdorin fuqinë e operatorëve të mbingarkuar pa e kthyer programin në një kuti të zezë.

Për më pak të aftë, për fat të keq, është e lehtë për të bërë një gabim. Ndërtuesit me një argument të vetëm dhe operatorët e konvertimit të tipit të nënkuptuar mund të jenë veçanërisht të mundimshëm sepse thirrjet e tyre nuk përputhen gjithmonë në Kodi i burimit programet. Kjo çon në programe, sjellja e të cilëve është shumë e vështirë për t'u kuptuar. Një problem tjetër lind kur mbingarkohen operatorë të tillë si && dhe II, sepse kalimi nga operatorët e integruar në funksionet e shkruara nga përdoruesi rezulton në ndryshime të vogla semantike që janë të lehta për t'u anashkaluar. Së fundi, shumë operatorë janë të lidhur me njëri-tjetrin sipas rregullave standarde, dhe për shkak të operatorëve të mbingarkuar, marrëdhëniet e pranuara përgjithësisht ndonjëherë shkelen.

Në rregullat e mëposhtme, jam përpjekur të shpjegoj se kur dhe si përdoren operatorët e mbingarkuar, si sillen, si duhet të lidhen me njëri-tjetrin dhe si mund të kontrollohet e gjithë kjo. Pasi të keni zotëruar materialin në këtë kapitull, do të mbingarkoni (ose nuk mbingarkoni) operatorët me besimin e një profesionisti të vërtetë.

Shkarko falas e-libër në një format të përshtatshëm, shikoni dhe lexoni:
Shkarkoni librin Të përfitoni sa më shumë nga C++ - 35 këshilla të reja për të përmirësuar programet dhe projektet tuaja - Meyers S. - fileskachat.com, shkarkim i shpejtë dhe pa pagesë.

Shkarkoni djvu
Më poshtë mund ta blini këtë libër me çmimin më të mirë të zbritur me dërgesë në të gjithë Rusinë.

Scott Meyers

Përdorimi efektiv i C++. 55 Mënyra të sigurta për të përmirësuar strukturën dhe kodin e programeve tuaja

Reagime për edicionin e tretëpërdorim efektiv C++

libër nga Scott Meyers Duke përdorur C++ në mënyrë efektive, botimi i tretëështë përqendrimi i përvojës së programimit - përvoja që pa të do t'ju kishte ardhur me një çmim të lartë. Ky libër është një burim i shkëlqyer që ia rekomandoj kujtdo që shkruan C++ në mënyrë profesionale.

Peter Dulimov, ME, Inxhinier, Njësia e Vlerësimit dhe Kërkimit NAVSYSCOM, Australi

Edicioni i tretë mbetet libri më i mirë se si të bashkohen të gjitha pjesët e C++ për të krijuar programe efikase dhe të qëndrueshme nga brenda. Nëse pretendoni të jeni programues C++, duhet ta lexoni.

Eric Nagler, konsulent, lektor dhe autor i Learning C++

Botimi i parë i këtij libri ishte një nga një numër i vogël (shumë i paktë) librash që kanë përmirësuar vërtet nivelin tim si një zhvillues profesionist softuerësh. Ashtu si librat e tjerë të kësaj serie, ai ishte praktik dhe i lehtë për t'u lexuar, por përmbante edhe shumë këshilla të rëndësishme. "Përdorimi efektiv C++", botimi i tretë, vazhdon këtë traditë. C++ është shumë gjuhë e fuqishme programimit. Nëse C ju jep një litar për t'u ngjitur në majë të një mali, atëherë C++ është një dyqan plot me lloj-lloj njerëzish që janë të gatshëm t'ju ndihmojnë të lidhni nyjet në atë litar. Zotërimi i materialit në këtë libër do të rrisë padyshim aftësinë tuaj për të përdorur C++ në mënyrë efektive dhe për të mos vdekur nga tendosja.

Jack W. Reeves, Drejtori Ekzekutiv Bleading Edge Software Technologies

Të gjithë zhvillues i ri, i cili vjen në ekipin tim, menjëherë merr detyrën - të lexojë këtë libër.

Michael Lanzetta, inxhinier kryesor i softuerit

E lexova edicionin e parë të Efektive C++ rreth 9 vjet më parë dhe shpejt u bë një nga librat e mi të preferuar në C++. Sipas mendimit tim, përdorimi efektiv i C++ Edicioni i 3-të mbetet një lexim i domosdoshëm për këdo që dëshiron të programojë në mënyrë efektive në C++. Ne do të jetojmë në një botë më të mirë nëse programuesit e C++ lexojnë këtë libër përpara se të shkruajnë rreshtin e parë të kodit profesional.

Danny Rabbani, Inxhinier Softuerësh

Edicioni i parë i Përdorimi efektiv i C++ nga Scott Meyers më erdhi kur isha një programues i zakonshëm dhe u përpoqa shumë për të bërë punën më të mirë që më ishte caktuar. Dhe ishte një shpëtimtar! Kam zbuluar se këshilla e Meyers është praktike dhe efektive, se ajo jep 100% atë që premton. Edicioni i tretë ju ndihmon të aplikoni C++ në projektet serioze të softuerit të sotëm duke ofruar informacion rreth veglave dhe veçorive më të fundit të gjuhës. Isha i kënaqur kur zbulova se mund të gjeja shumë gjëra të reja dhe interesante për veten time në botimin e tretë të një libri që mendoja se e njihja shumë mirë.

Michael Topic, Menaxher Programi Teknik

Ky është një udhëzues autoritar nga Scott Meyers, guru i C++, për këdo që dëshiron të përdorë C++ në mënyrë të sigurt dhe efikase, ose që po kalon në C++ nga çdo gjuhë tjetër e orientuar nga objekti. Ky libër përmban informacione të vlefshme të paraqitura në një stil të qartë, konciz, argëtues dhe depërtues.

Siddhartha Karan Singh, Zhvillues i Softuerit

Faleminderit

Përdorimi efektiv i C++ ka qenë rreth 15 vjet, dhe unë fillova të mësoj C++ rreth 5 vjet përpara se ta shkruaja. Kështu, puna për këtë projekt ka rreth 20 vjet që po vazhdon. Gjatë kësaj kohe, kam marrë urime, komente, korrigjime dhe ndonjëherë vëzhgime mahnitëse nga qindra (mijëra?) njerëz. Secili prej tyre ndihmoi në zhvillimin e "Përdorimi i C++ në mënyrë efektive". Unë u jam mirënjohës të gjithëve.

Unë hoqa dorë nga përpjekjet për të kujtuar se ku dhe çfarë kam mësuar vetë shumë kohë më parë, por nuk mund të mos përmend një burim sepse e përdor atë gjatë gjithë kohës. Këto janë grupet e lajmeve Usenet, veçanërisht comp.lang.c++.moderated dhe comp.std.c++. Shumë nga rregullat në këtë libër (ndoshta shumica) u krijuan si rezultat i të menduarit rreth ideve teknike të diskutuara në këto grupe.

Steve Dewhurst më ndihmoi në përzgjedhjen e materialit të ri për botimin e tretë të librit. Në pikën 11, ideja e zbatimit të operatorit= operator me kopjim dhe shkëmbim është marrë nga shënimet e Herb Sutter, përkatësisht problemi 13 i librit të tij Exceptional C++ (Addison-Wesley, 2000). Ideja e marrjes së një burimi si inicializim (Rregulli 13) vjen nga Gjuha e Programimit C++ (Addison-Wesley, 2002) nga Bjarne Stroustrup. Ideja e rregullit 17 është marrë nga seksioni "Praktikat më të mira" të faqes së internetit Boost shared_ptr (http:// boost.org/libs/smart_ptr/shared_ptr.htm#BestPractices) dhe është përpunuar bazuar në materialin nga problemi 21 në libër. Herb Sutter "Më e jashtëzakonshme C++" (Addison-Wesley, 2002). Rregulli 29 u frymëzua nga eksplorimi i gjerë i Herb Sutter për këtë temë në problemat 8-19 të Exceptional C++, si dhe problemet 17-23 të C++ Më të jashtëzakonshme dhe problemet 11-13 të librit të tij Exceptional C++. Style" (Addison-Wesley, 2005). David Abrahams më ndihmoi të kuptoj më mirë tre parimet e garantimit të sigurisë së përjashtimit. Idioma e ndërfaqes jo virtuale (NVI) në pikën 35 është marrë nga kolona "Virtualiteti" e Herb Sutter në numrin shtator 2001 të C/C++ Users Journal. Modelet e dizajnit "Template Method" dhe "Strategy" të përmendura në të njëjtin rregull janë marrë nga libri "Design Patterns" (Addison-Wesley, 1995) nga Erich Gamma, Richard Helm, Ralph Johnson (Ralf Johnson) dhe John Vlissides (John Vlissides). Ideja e përdorimit të idiomës NVI në rregullin 37 u sugjerua nga Hendrik Schober. Kontributi i David Smallberg është zbatimi i grupit të përshkruar në pikën 38. Vëzhgimi i bërë në pikën 39 se optimizimi i një klase bazë boshe është thelbësisht i pamundur me trashëgimi të shumëfishtë është marrë nga libri i David Vandevoorde dhe Nicholas M. Jossuthis (Nickolai M. Josuttis) "Templates C++" (Addison-Wesley, 2003). Në artikullin 42, ideja ime fillestare se për çfarë është fjala kyçe e emrit të tipit bazohet në FAQ të C++ dhe C (http://www.comeaucomputing.com/techtalk/). #typename) të mbajtur nga Greg Comeau dhe Leor Zolman më ndihmoi të kuptoj se kjo pikëpamje është e gabuar (faji im, jo ​​i Gregut). Tema e Rregullit 46 erdhi nga fjalimi i Dan Saks "Si të bësh miq të rinj". Ideja në fund të rregullit 52, që nëse deklaroni një version të ri, duhet të deklaroni të gjithë të tjerët, është paraqitur në problemin 22 të Exceptional C++ të Herb Sutter. Kuptimi im për procesin e rishikimit të Boost (përmbledhur në pikën 55) është sqaruar nga David Abrahams.

Scott Meyers

Përdorimi efektiv i C++. 55 Mënyra të sigurta për të përmirësuar strukturën dhe kodin e programeve tuaja

Reagime për edicionin e tretëPërdorimi efektiv i C++

libër nga Scott Meyers Duke përdorur C++ në mënyrë efektive, botimi i tretëështë përqendrimi i përvojës së programimit - përvoja që pa të do t'ju kishte ardhur me një çmim të lartë. Ky libër është një burim i shkëlqyer që ia rekomandoj kujtdo që shkruan C++ në mënyrë profesionale.

Peter Dulimov, ME, Inxhinier, Njësia e Vlerësimit dhe Kërkimit NAVSYSCOM, Australi

Edicioni i tretë mbetet libri më i mirë se si të bashkohen të gjitha pjesët e C++ për të krijuar programe efikase dhe të qëndrueshme nga brenda. Nëse pretendoni të jeni programues C++, duhet ta lexoni.

Eric Nagler, konsulent, lektor dhe autor i Learning C++

Botimi i parë i këtij libri ishte një nga një numër i vogël (shumë i paktë) librash që kanë përmirësuar vërtet nivelin tim si një zhvillues profesionist softuerësh. Ashtu si librat e tjerë të kësaj serie, ai ishte praktik dhe i lehtë për t'u lexuar, por përmbante edhe shumë këshilla të rëndësishme. "Përdorimi efektiv C++", botimi i tretë, vazhdon këtë traditë. C++ është një gjuhë programimi shumë e fuqishme. Nëse C ju jep një litar për t'u ngjitur në majë të një mali, atëherë C++ është një dyqan plot me lloj-lloj njerëzish që janë të gatshëm t'ju ndihmojnë të lidhni nyjet në atë litar. Zotërimi i materialit në këtë libër do të rrisë padyshim aftësinë tuaj për të përdorur C++ në mënyrë efektive dhe për të mos vdekur nga tendosja.

Jack W. Reeves, CEO i Bleading Edge Software Technologies

Çdo zhvilluesi i ri që bashkohet me ekipin tim i jepet menjëherë detyra për të lexuar këtë libër.

Michael Lanzetta, inxhinier kryesor i softuerit

E lexova edicionin e parë të Efektive C++ rreth 9 vjet më parë dhe shpejt u bë një nga librat e mi të preferuar në C++. Sipas mendimit tim, përdorimi efektiv i C++ Edicioni i 3-të mbetet një lexim i domosdoshëm për këdo që dëshiron të programojë në mënyrë efektive në C++. Ne do të jetojmë në një botë më të mirë nëse programuesit e C++ lexojnë këtë libër përpara se të shkruajnë rreshtin e parë të kodit profesional.

Danny Rabbani, Inxhinier Softuerësh

Edicioni i parë i Përdorimi efektiv i C++ nga Scott Meyers më erdhi kur isha një programues i zakonshëm dhe u përpoqa shumë për të bërë punën më të mirë që më ishte caktuar. Dhe ishte një shpëtimtar! Kam zbuluar se këshilla e Meyers është praktike dhe efektive, se ajo jep 100% atë që premton. Edicioni i tretë ju ndihmon të aplikoni C++ në projektet serioze të softuerit të sotëm duke ofruar informacion rreth veglave dhe veçorive më të fundit të gjuhës. Isha i kënaqur kur zbulova se mund të gjeja shumë gjëra të reja dhe interesante për veten time në botimin e tretë të një libri që mendoja se e njihja shumë mirë.

Michael Topic, Menaxher Programi Teknik

Ky është një udhëzues autoritar nga Scott Meyers, guru i C++, për këdo që dëshiron të përdorë C++ në mënyrë të sigurt dhe efikase, ose që po kalon në C++ nga çdo gjuhë tjetër e orientuar nga objekti. Ky libër përmban informacione të vlefshme të paraqitura në një stil të qartë, konciz, argëtues dhe depërtues.

Siddhartha Karan Singh, Zhvillues i Softuerit

Faleminderit

Përdorimi efektiv i C++ ka qenë rreth 15 vjet, dhe unë fillova të mësoj C++ rreth 5 vjet përpara se ta shkruaja. Kështu, puna për këtë projekt ka rreth 20 vjet që po vazhdon. Gjatë kësaj kohe, kam marrë urime, komente, korrigjime dhe ndonjëherë vëzhgime mahnitëse nga qindra (mijëra?) njerëz. Secili prej tyre ndihmoi në zhvillimin e "Përdorimi i C++ në mënyrë efektive". Unë u jam mirënjohës të gjithëve.

Unë hoqa dorë nga përpjekjet për të kujtuar se ku dhe çfarë kam mësuar vetë shumë kohë më parë, por nuk mund të mos përmend një burim sepse e përdor atë gjatë gjithë kohës. Këto janë grupet e lajmeve Usenet, veçanërisht comp.lang.c++.moderated dhe comp.std.c++. Shumë nga rregullat në këtë libër (ndoshta shumica) u krijuan si rezultat i të menduarit rreth ideve teknike të diskutuara në këto grupe.

Steve Dewhurst më ndihmoi në përzgjedhjen e materialit të ri për botimin e tretë të librit. Në pikën 11, ideja e zbatimit të operatorit= operator me kopjim dhe shkëmbim është marrë nga shënimet e Herb Sutter, përkatësisht problemi 13 i librit të tij Exceptional C++ (Addison-Wesley, 2000). Ideja e marrjes së një burimi si inicializim (Rregulli 13) vjen nga Gjuha e Programimit C++ (Addison-Wesley, 2002) nga Bjarne Stroustrup. Ideja e rregullit 17 është marrë nga seksioni "Praktikat më të mira" të faqes së internetit Boost shared_ptr (http:// boost.org/libs/smart_ptr/shared_ptr.htm#BestPractices) dhe është përpunuar bazuar në materialin nga problemi 21 në libër. Herb Sutter "Më e jashtëzakonshme C++" (Addison-Wesley, 2002). Rregulli 29 u frymëzua nga eksplorimi i gjerë i Herb Sutter për këtë temë në problemat 8-19 të Exceptional C++, si dhe problemet 17-23 të C++ Më të jashtëzakonshme dhe problemet 11-13 të librit të tij Exceptional C++. Style" (Addison-Wesley, 2005). David Abrahams më ndihmoi të kuptoj më mirë tre parimet e garantimit të sigurisë së përjashtimit. Idioma e ndërfaqes jo virtuale (NVI) në pikën 35 është marrë nga kolona "Virtualiteti" e Herb Sutter në numrin shtator 2001 të C/C++ Users Journal. Modelet e dizajnit "Template Method" dhe "Strategy" të përmendura në të njëjtin rregull janë marrë nga libri "Design Patterns" (Addison-Wesley, 1995) nga Erich Gamma, Richard Helm, Ralph Johnson (Ralf Johnson) dhe John Vlissides (John Vlissides). Ideja e përdorimit të idiomës NVI në rregullin 37 u sugjerua nga Hendrik Schober. Kontributi i David Smallberg është zbatimi i grupit të përshkruar në pikën 38. Vëzhgimi i bërë në pikën 39 se optimizimi i një klase bazë boshe është thelbësisht i pamundur me trashëgimi të shumëfishtë është marrë nga libri i David Vandevoorde dhe Nicholas M. Jossuthis (Nickolai M. Josuttis) "Templates C++" (Addison-Wesley, 2003). Në artikullin 42, ideja ime fillestare se për çfarë është fjala kyçe e emrit të tipit bazohet në FAQ të C++ dhe C (http://www.comeaucomputing.com/techtalk/). #typename) të mbajtur nga Greg Comeau dhe Leor Zolman më ndihmoi të kuptoj se kjo pikëpamje është e gabuar (faji im, jo ​​i Gregut). Tema e Rregullit 46 erdhi nga fjalimi i Dan Saks "Si të bësh miq të rinj". Ideja në fund të rregullit 52, që nëse deklaroni një version të ri, duhet të deklaroni të gjithë të tjerët, është paraqitur në problemin 22 të Exceptional C++ të Herb Sutter. Kuptimi im për procesin e rishikimit të Boost (përmbledhur në pikën 55) është sqaruar nga David Abrahams.

Të gjitha sa më sipër kanë të bëjnë se ku dhe nga kush kam mësuar diçka, pavarësisht se kush e ka publikuar i pari materialin për temën përkatëse.

Shënimet e mia gjithashtu thonë se kam përdorur informacione nga Steve Clamage, Antoine Trux, Timothy Knox dhe Mike Kaebling, megjithëse për fat të keq nuk specifikohet se ku dhe si.

Draftet e edicionit të parë të shqyrtuara nga Tom Cargill, Glenn Carroll, Tony Davis, Brian Kernigan, Jak Kirman, Doug Lea, Moises Lejter), Eugene Santos Jr. (Eugene Santos, Jr), John Shewchuk, John Stasko, Bjarne Stroustrup, Barbara Tilly dhe Nancy L. Urbano. Përveç kësaj, kërkesa për përmirësime që u përfshinë në botimet e mëvonshme u bënë nga Nancy L. Urbano, Chris Treichel, David Corbin, Paul Gibson, Steve Vinoski, Tom Tom Cargill, Neil Rhodes, David Bern, Russ Williams, Robert Brazile, Doug Morgan , Uwe Steinmuller, Mark Somer Mark Somer, Doug Moore, David Smallberg, Seith Meltzer, Oleg Steinbuk, David Papurt, Tony Hansen, Peter McCluskey ), Stefan Kuhlins, David Braunegg, Paul Chisholm, Adam Zell, Clovis Tondo, Mike Koelbling, Natraj Kini, Lars Numan, Greg Lutz, Tim Johnson, John Lakos, Roger Scott, Scott Frohman, Alan R ooks), Robert Poor, Eric Nagler, Anton Trax, Cade Roux, Chandrika Gokul, Randy Mangoba dhe Glenn Teitelbaum.

Draftet e edicionit të dytë të shqyrtuara nga: Derek Bosch, Tim Johnson, Brian Kernighan, Junichi Kimura, Scott Lewandowski, Laura Michaels, David Smallberg, Clovis Tonado, Chris Van Wyk dhe Oleg Zabluda. Botimet e mëvonshme përfituan nga komentet e Daniel Steinberg, Arunprasad Marathe, Doug Stapp, Robert Hall, Cheryl Ferguson, Gary Bartlett, Michael Tamm (Michael Tamm), Kendall Beaman, Eric Nagler, Max Hailperin, Joe Gottman, Richard Weeks, Valentin Bonnard, Jun Hee, Tim King, Don Mailer, Ted Hill, Marc Harrison, Michael Rubinstein, Marc Rodgers, David Goh, Brenton Cooper, Andy Thomas-Cramer, Anton Thrax, John Walt, Brian Sharon, Liam Fitzpatric, Bernd Mohr, Harry Yee (Gary Yee), John O "Hanley (John O" Hanley), Brady Patreson (Brady Paterson), Christopher Peterson (Krishti opher Peterson), Feliks Kluzniak, Isi Dunetz, Christopher Creutzi, Ian Cooper, Carl Harris, Marc Stickel, Clay Budin ), Panayotis Matsinopulos, David Smallberg, Herb Sutter, Pajo Misljencevic, Giulio Agostini, Fredrik Blonqvistnyder, Jim Witold Kuzminski, Kazunobu Kuriyama, Michael Christensen, Jorge Yanez Teruel, Mark Davis, Marty Rabinowitz, Ares Lagae dhe Alexander Medvedev.

Scott Meyers

Përdorimi efektiv i C++. 55 Mënyra të sigurta për të përmirësuar strukturën dhe kodin e programeve tuaja

Reagime për edicionin e tretë

Përdorimi efektiv i C++

libër nga Scott Meyers Duke përdorur C++ në mënyrë efektive, botimi i tretëështë përqendrimi i përvojës së programimit - përvoja që pa të do t'ju kishte ardhur me një çmim të lartë. Ky libër është një burim i shkëlqyer që ia rekomandoj kujtdo që shkruan C++ në mënyrë profesionale.

Peter Dulimov, ME, Inxhinier, Njësia e Vlerësimit dhe Kërkimit NAVSYSCOM, Australi

Edicioni i tretë mbetet libri më i mirë se si të bashkohen të gjitha pjesët e C++ për të krijuar programe efikase dhe të qëndrueshme nga brenda. Nëse pretendoni të jeni programues C++, duhet ta lexoni.

Eric Nagler, konsulent, lektor dhe autor i Learning C++

Botimi i parë i këtij libri ishte një nga një numër i vogël (shumë i paktë) librash që kanë përmirësuar vërtet nivelin tim si një zhvillues profesionist softuerësh. Ashtu si librat e tjerë të kësaj serie, ai ishte praktik dhe i lehtë për t'u lexuar, por përmbante edhe shumë këshilla të rëndësishme. "Përdorimi efektiv C++", botimi i tretë, vazhdon këtë traditë. C++ është një gjuhë programimi shumë e fuqishme. Nëse C ju jep një litar për t'u ngjitur në majë të një mali, atëherë C++ është një dyqan plot me lloj-lloj njerëzish që janë të gatshëm t'ju ndihmojnë të lidhni nyjet në atë litar. Zotërimi i materialit në këtë libër do të rrisë padyshim aftësinë tuaj për të përdorur C++ në mënyrë efektive dhe për të mos vdekur nga tendosja.

Jack W. Reeves, CEO i Bleading Edge Software Technologies

Çdo zhvilluesi i ri që bashkohet me ekipin tim i jepet menjëherë detyra për të lexuar këtë libër.

Michael Lanzetta, inxhinier kryesor i softuerit

E lexova edicionin e parë të Efektive C++ rreth 9 vjet më parë dhe shpejt u bë një nga librat e mi të preferuar në C++. Sipas mendimit tim, përdorimi efektiv i C++ Edicioni i 3-të mbetet një lexim i domosdoshëm për këdo që dëshiron të programojë në mënyrë efektive në C++. Ne do të jetojmë në një botë më të mirë nëse programuesit e C++ lexojnë këtë libër përpara se të shkruajnë rreshtin e parë të kodit profesional.

Danny Rabbani, Inxhinier Softuerësh

Edicioni i parë i Përdorimi efektiv i C++ nga Scott Meyers më erdhi kur isha një programues i zakonshëm dhe u përpoqa shumë për të bërë punën më të mirë që më ishte caktuar. Dhe ishte një shpëtimtar! Kam zbuluar se këshilla e Meyers është praktike dhe efektive, se ajo jep 100% atë që premton. Edicioni i tretë ju ndihmon të aplikoni C++ në projektet serioze të softuerit të sotëm duke ofruar informacion rreth veglave dhe veçorive më të fundit të gjuhës. Isha i kënaqur kur zbulova se mund të gjeja shumë gjëra të reja dhe interesante për veten time në botimin e tretë të një libri që mendoja se e njihja shumë mirë.

Michael Topic, Menaxher Programi Teknik

Ky është një udhëzues autoritar nga Scott Meyers, guru i C++, për këdo që dëshiron të përdorë C++ në mënyrë të sigurt dhe efikase, ose që po kalon në C++ nga çdo gjuhë tjetër e orientuar nga objekti. Ky libër përmban informacione të vlefshme të paraqitura në një stil të qartë, konciz, argëtues dhe depërtues.

Siddhartha Karan Singh, Zhvillues i Softuerit

Faleminderit

Përdorimi efektiv i C++ ka qenë rreth 15 vjet, dhe unë fillova të mësoj C++ rreth 5 vjet përpara se ta shkruaja. Kështu, puna për këtë projekt ka rreth 20 vjet që po vazhdon. Gjatë kësaj kohe, kam marrë urime, komente, korrigjime dhe ndonjëherë vëzhgime mahnitëse nga qindra (mijëra?) njerëz. Secili prej tyre ndihmoi në zhvillimin e "Përdorimi i C++ në mënyrë efektive". Unë u jam mirënjohës të gjithëve.

Unë hoqa dorë nga përpjekjet për të kujtuar se ku dhe çfarë kam mësuar vetë shumë kohë më parë, por nuk mund të mos përmend një burim sepse e përdor atë gjatë gjithë kohës. Këto janë grupet e lajmeve Usenet, veçanërisht comp.lang.c++.moderated dhe comp.std.c++. Shumë nga rregullat në këtë libër (ndoshta shumica) u krijuan si rezultat i të menduarit rreth ideve teknike të diskutuara në këto grupe.

Steve Dewhurst më ndihmoi në përzgjedhjen e materialit të ri për botimin e tretë të librit. Në pikën 11, ideja e zbatimit të operatorit= me kopjim dhe shkëmbim është marrë nga shënimet e Herb Sutter, veçanërisht nga numri 13 i librit të tij Exceptional C++ (Addison-Wesley, 2000). Ideja e marrjes së një burimi si inicializim (Rregulli 13) vjen nga Gjuha e Programimit C++ (Addison-Wesley, 2002) nga Bjarne Stroustrup. Ideja e rregullit 17 është marrë nga seksioni "Praktikat më të mira" të faqes së internetit Boost shared_ptr (http:// boost.org/libs/smart_ptr/shared_ptr.htm#BestPractices) dhe është përpunuar bazuar në materialin nga problemi 21 në libër. Herb Sutter "Më e jashtëzakonshme C++" (Addison-Wesley, 2002). Rregulli 29 u frymëzua nga eksplorimi i gjerë i Herb Sutter për këtë temë në problemat 8-19 të Exceptional C++, si dhe problemet 17-23 të C++ Më të jashtëzakonshme dhe problemet 11-13 të librit të tij Exceptional C++. Style" (Addison-Wesley, 2005). David Abrahams më ndihmoi të kuptoj më mirë tre parimet e garantimit të sigurisë së përjashtimit. Idioma e ndërfaqes jo virtuale (NVI) në pikën 35 është marrë nga kolona "Virtualiteti" e Herb Sutter në numrin shtator 2001 të C/C++ Users Journal. Modelet e dizajnit "Template Method" dhe "Strategy" të përmendura në të njëjtin rregull janë marrë nga libri "Design Patterns" (Addison-Wesley, 1995) nga Erich Gamma, Richard Helm, Ralph Johnson (Ralf Johnson) dhe John Vlissides (John Vlissides). Ideja e përdorimit të idiomës NVI në rregullin 37 u sugjerua nga Hendrik Schober. Kontributi i David Smallberg është zbatimi i grupit të përshkruar në pikën 38. Vëzhgimi i bërë në pikën 39 se optimizimi i një klase bazë boshe është thelbësisht i pamundur me trashëgimi të shumëfishtë është marrë nga libri i David Vandevoorde dhe Nicholas M. Jossuthis (Nickolai M. Josuttis) "Templates C++" (Addison-Wesley, 2003). Në artikullin 42, ideja ime fillestare se për çfarë është fjala kyçe e emrit të tipit bazohet në FAQ të C++ dhe C (http://www.comeaucomputing.com/techtalk/). #typename) të mbajtur nga Greg Comeau dhe Leor Zolman më ndihmoi të kuptoj se kjo pikëpamje është e gabuar (faji im, jo ​​i Gregut). Tema e Rregullit 46 erdhi nga fjalimi i Dan Saks "Si të bësh miq të rinj". Ideja në fund të rregullit 52, që nëse deklaroni një version të ri, duhet të deklaroni të gjithë të tjerët, është paraqitur në problemin 22 të Exceptional C++ të Herb Sutter. Kuptimi im për procesin e rishikimit të Boost (përmbledhur në pikën 55) është sqaruar nga David Abrahams.

Të gjitha sa më sipër kanë të bëjnë se ku dhe nga kush kam mësuar diçka, pavarësisht se kush e ka publikuar i pari materialin për temën përkatëse.

Shënimet e mia gjithashtu thonë se kam përdorur informacione nga Steve Clamage, Antoine Trux, Timothy Knox dhe Mike Kaebling, megjithëse për fat të keq nuk specifikohet se ku dhe si.

Draftet e edicionit të parë të shqyrtuara nga Tom Cargill, Glenn Carroll, Tony Davis, Brian Kernigan, Jak Kirman, Doug Lea, Moises Lejter), Eugene Santos Jr. (Eugene Santos, Jr), John Shewchuk, John Stasko, Bjarne Stroustrup, Barbara Tilly dhe Nancy L. Urbano. Përveç kësaj, kërkesa për përmirësime që u përfshinë në botimet e mëvonshme u bënë nga Nancy L. Urbano, Chris Treichel, David Corbin, Paul Gibson, Steve Vinoski, Tom Tom Cargill, Neil Rhodes, David Bern, Russ Williams, Robert Brazile, Doug Morgan , Uwe Steinmuller, Mark Somer Mark Somer, Doug Moore, David Smallberg, Seith Meltzer, Oleg Steinbuk, David Papurt, Tony Hansen, Peter McCluskey ), Stefan Kuhlins, David Braunegg, Paul Chisholm, Adam Zell, Clovis Tondo, Mike Koelbling, Natraj Kini, Lars Numan, Greg Lutz, Tim Johnson, John Lakos, Roger Scott, Scott Frohman, Alan R ooks), Robert Poor, Eric Nagler, Anton Trax, Cade Roux, Chandrika Gokul, Randy Mangoba dhe Glenn Teitelbaum.

Draftet e edicionit të dytë të shqyrtuara nga: Derek Bosch, Tim Johnson, Brian Kernighan, Junichi Kimura, Scott Lewandowski, Laura Michaels, David Smallberg, Clovis Tonado, Chris Van Wyk dhe Oleg Zabluda. Botimet e mëvonshme përfituan nga komentet e Daniel Steinberg, Arunprasad Marathe, Doug Stapp, Robert Hall, Cheryl Ferguson, Gary Bartlett, Michael Tamm (Michael Tamm), Kendall Beaman, Eric Nagler, Max Hailperin, Joe Gottman, Richard Weeks, Valentin Bonnard, Jun Hee, Tim King, Don Mailer, Ted Hill, Marc Harrison, Michael Rubinstein, Marc Rodgers, David Goh, Brenton Cooper, Andy Thomas-Cramer, Anton Thrax, John Walt, Brian Sharon, Liam Fitzpatric, Bernd Mohr, Harry Yee (Gary Yee), John O "Hanley (John O" Hanley), Brady Patreson (Brady Paterson), Christopher Peterson (Krishti opher Peterson), Feliks Kluzniak, Isi Dunetz, Christopher Creutzi, Ian Cooper, Carl Harris, Marc Stickel, Clay Budin ), Panayotis Matsinopulos, David Smallberg, Herb Sutter, Pajo Misljencevic, Giulio Agostini, Fredrik Blonqvistnyder, Jim Witold Kuzminski, Kazunobu Kuriyama, Michael Christensen, Jorge Yanez Teruel, Mark Davis, Marty Rabinowitz, Ares Lagae dhe Alexander Medvedev.

Draftet e hershme të pjesshme të këtij botimi u shqyrtuan nga: Brian Kernighan, Angelique Langer, Jesse Luchley, Roger P. Pedersen, Chris Van Wyck, Nicholas Stroustrup dhe Hendrik Schober. Shqyrtimi i plotë i draftit u shqyrtua nga: Leor Zolman, Mike Tsao, Eric Nagler, Gene Gutnick, David Abrahams, Gerhard Kreuser, Drosos Kouronis, Brian Kernighan, Andrew Krims, Balogh Pal, Emily Jagdhar, Evgeny Kalenkovic, Mike Rose, Enrico Burkera , Jack Reeves, Steve Schirippa, Martin Fallenstedt, Timothy Knox, Yun Bai, Michael Lanzetta, Philip Janert, Judo Bartolucci, Michael Topic, Jeff Sherpeltz, Chris Nauroth, Nishant Mittal, Jeff Sommers, Hal Moroff, Vincent Chang Manis, Brendogn Lee, Jim Meehan, Alan Geller, Siddhartha Singh, Sam Lee, Sasan Dashtinejad, Alex Martin, Steve Kai, Thomas Fruchterman, Corey Hicks, David Smallberg, Gunawardan Kakulapati, Danny Rabbani, Jake Cohen, Hendrik Schuber, Paco Viziana, Glenny D. Oldham, Nicholas Stroustrup, Matthew Wilson, Andrei Alexandrescu, Tim Johnson, Leon Matthews, Peter Dulimov dhe Kevlin Henney. Draftet e disa paragrafëve individualë u shqyrtuan gjithashtu nga Herb Sutter dhe Attila F. Feher.

Rishikimi i një dorëshkrimi të papërpunuar (dhe ndoshta jo të plotë) është punë e vështirë dhe afatet e ngushta vetëm e bëjnë më të vështirë. I jam mirënjohës të gjithëve që shprehën dëshirën për të më ndihmuar për këtë.

Rishikimi i një dorëshkrimi është edhe më i vështirë nëse nuk keni ide për materialin, por nuk duhet ta humbisni asnje pasaktësi që mund të depërtojnë në tekst. Është e mahnitshme që ka njerëz që pranojnë të redaktojnë tekstet. Christa Meadowbrook ishte redaktore e këtij libri dhe ishte në gjendje të dallonte mjaft gabime që të gjithë të tjerët i humbën.

Leor Zolman rishikoi dorëshkrimin për të gjitha mostrat e kodit në përpilues të ndryshëm dhe më pas e bëri përsëri pasi bëra ndryshime. Nëse mbeten ndonjë gabim, unë jam përgjegjës për to, jo Lheor.

Carl Vigers dhe veçanërisht Tim Johnson shkruan një tekst të shkurtër por të dobishëm për kopertinën.

John Waite, redaktor i dy botimeve të para të këtij libri, pa maturi pranoi të punonte përsëri në atë cilësi. Asistentja e tij, Denise Michelsen, i përgjigjej pa ndryshim me një buzëqeshje të këndshme vërejtjeve të mia të shpeshta dhe të bezdisshme (të paktën kështu mendoj, megjithëse nuk e kam takuar kurrë personalisht). Julia Nakhil "tërhoqi kashtën e shkurtër", ajo duhej të ishte përgjegjëse për prodhimin e këtij libri. Për gjashtë javë, ajo u ul natën për të mbajtur orarin e saj pa e humbur qetësinë. John Fuller (shefi i saj) dhe Marty Rabinowitz (shefi i tij) ishin gjithashtu të përfshirë drejtpërdrejt në procesin e prodhimit. Detyrat zyrtare të Vanessa Moore ishin të kornizonte librin në FrameMaker dhe të krijonte tekstin PDF, por ajo kontribuoi vullnetarisht në Shtojcën B dhe e formatoi për printim në kopertinën e brendshme. Solveig Huegland ndihmoi me indeksin. Sandra Schroeder dhe Chuti Prasercit ishin përgjegjëse për dizajnin e kopertinës. Ishte Chuti që duhej të ribënte kopertinën sa herë që thosha: “Po ta vendosim këtë foto, por me një shirit të një ngjyre tjetër?”. Chanda Leri-Couty është plotësisht i rraskapitur nga marketingu i librit.

Gjatë muajve që punova për dorëshkrimin, seriali televiziv Buffy the Vampire Slayer më ndihmoi të largoja stresin në fund të ditës. U desh shumë përpjekje për të përjashtuar fjalimin e Buffy-t nga faqet e këtij libri.

Kathy Reed më mësoi se si të programoja në vitin 1971 dhe jam e lumtur që mbesim miq edhe sot e kësaj dite. Donald French punësoi mua dhe Moses Legter për të zhvilluar mësime C++ në 1989 (gjë që më bëri vërtetë mësojnë C++), dhe në vitin 1991 më ftoi t'i prezantoj në kompjuterin Stratus. Pastaj studentët më inkurajuan të shkruaj atë që më vonë u bë botimi i parë i këtij libri. Don gjithashtu më prezantoi me John White, i cili pranoi ta botonte.

Gruaja ime, Nancy L. Urbano, vazhdon të inkurajojë shkrimin tim, edhe pas shtatë librave të botuar, përshtatjeve të CD-ve dhe një disertacioni. Ajo ka një durim të jashtëzakonshëm. Pa të, nuk do të kisha mundur kurrë të bëja atë që bëra.

Nga fillimi deri në fund, qeni ynë Persefona ka qenë shoqëruesja ime altruiste. Fatkeqësisht, ajo mori pjesë në pjesën më të madhe të projektit ndërsa ishte tashmë në urnën e varrimit. Na mungon shumë ajo.

Parathënie

E shkrova draftin e parë të Efektive C++ në vitin 1991. Kur erdhi koha për botimin e dytë në 1997, e përditësova ndjeshëm materialin, por duke mos dashur të ngatërroj lexuesit e njohur me botimin e parë, u përpoqa të ruaj strukturën ekzistuese: 48 të origjinali 50 rregullat mbetën në thelb të pandryshuara. Krahasuar me një libër dhe një shtëpi, botimi i dytë ishte si duke ridekoruar– ringjitja e letër-muri, lyerja me ngjyra të tjera dhe zëvendësimi i pajisjeve të ndriçimit.

Në edicionin e tretë, u futa në shumë më tepër. (Ishte një kohë kur doja të rindërtoja gjithçka nga themeli.) Gjuha C++ ka ndryshuar shumë që nga viti 1991, dhe qëllimet e këtij libri—të nxirrte në pah gjërat më të rëndësishme dhe t'i paraqiste ato në një koleksion kompakt rekomandimesh —nuk i përshtatet më grupit të rregullave të formuluara 15 vjet më parë. Në vitin 1991, ishte e arsyeshme të supozohej se programuesit me përvojë në C po kalonin në C++. Tani, ata që shkruanin në Java ose C# kanë po aq gjasa të përfshihen. Në vitin 1991, trashëgimia dhe programimi i orientuar drejt objekteve ishin të reja për shumicën e programuesve. Tani këto janë koncepte të njohura dhe fushat që njerëzit kanë nevojë për më shumë sqarime janë përjashtimet, modelet dhe programimi i përgjithshëm. Në vitin 1991, askush nuk kishte dëgjuar për modelet e dizajnit. Tani, pa i përmendur ato, përgjithësisht është e vështirë të diskutohet sistemet softuerike. Në vitin 1991, puna për një standard zyrtar C++ sapo kishte filluar, standardi tani është 8 vjeç dhe po punohet për versionin tjetër.

Për të llogaritur të gjitha këto ndryshime, vendosa të filloj fletë e pastër dhe pyeta veten: "Çfarë këshille do t'i jepnit për praktikimin e programuesve C++ në 2005?" Rezultati është një grup rregullash të përfshira në botimin e ri. Ky libër përfshin kapituj të rinj mbi programimin e modeleve dhe menaxhimin e burimeve. Në fakt, shabllonet kalojnë si një fije e kuqe nëpër tekst, pasi nuk ka pak në C++ moderne pa to. Libri përfshin gjithashtu materiale mbi programimin sipas përjashtimeve, modelet e projektimit dhe pajisjet e reja të bibliotekës, të përshkruara në Raportin Teknik 1 (TR1) (ky dokument mbulohet në pikën 54). Ai njeh gjithashtu faktin se qasjet dhe teknikat që funksionojnë mirë në sistemet me një fije mund të mos jenë të zbatueshme për ato me shumë fije. Më shumë se gjysma e materialeve në këtë botim janë tema të reja. Megjithatë, shumë nga informacionet themelore nga botimi i dytë mbeten të rëndësishme, kështu që unë kam gjetur një mënyrë për ta përsëritur atë në një formë ose në një tjetër (shih shtojcën B për korrespondencën midis rregullave të botimit të dytë dhe të tretë).

Jam munduar maksimalisht që këtë libër ta bëj sa më të dobishëm, por sigurisht që nuk mendoj se është perfekt. Nëse ju duket se disa nga rregullat e mësipërme nuk mund të konsiderohen të zbatueshme universalisht, se ka një mënyrë më të mirë për të zgjidhur problemin e formuluar, ose se diskutimi i disa probleme teknike jo mjaftueshëm i qartë, i paplotë, mund të jetë mashtrues, ju lutem më njoftoni. Nëse gjeni gabime të çfarëdo lloji—teknike, gramatikore, tipografike, çfarëdo—më njoftoni edhe për këtë. Në edicionin e ardhshëm, me kënaqësi do të përmend këdo që më sjell një problem në vëmendje.

Pavarësisht se në edicionin e ri numri i rregullave është rritur në 55, natyrisht, nuk mund të thuhet se janë marrë në konsideratë të gjitha dhe të gjitha çështjet. Por formulimi i një sërë rregullash të tilla, të cilat duhet të ndiqen pothuajse në të gjitha aplikacionet pothuajse gjithmonë, është më i vështirë sesa mund të duket në shikim të parë. Nëse keni sugjerime se çfarë tjetër duhet të përfshihet, unë do të jem i lumtur t'i shqyrtoj ato.


Stafford, Oregon, Prill 2005

Prezantimi

Është një gjë për të studiuar bazat gjuhë, dhe krejt tjetër - të mësosh të hartosh dhe zbatosh programe efektive. Kjo është veçanërisht e vërtetë për C++, e cila njihet për fuqinë dhe ekspresivitetin e saj të jashtëzakonshëm. Puna në C++, kur përdoret siç duhet, mund të jetë argëtuese. Një shumëllojshmëri e gjerë projektesh mund të shprehen drejtpërdrejt dhe të zbatohen në mënyrë efektive. Një grup klasash, funksionesh dhe shabllonesh të zgjedhur me kujdes dhe të zbatuar mirë do të ndihmojë që një program të jetë i thjeshtë, intuitiv, efikas dhe praktikisht pa gabime. Me aftësitë e duhura, shkrimi i programeve efektive C++ nuk është aspak i vështirë. Megjithatë, kur përdoret në mënyrë të papërshtatshme, C++ mund të prodhojë kod konfuz, të vështirë për t'u mirëmbajtur dhe thjesht të gabuar.

Qëllimi i këtij libri është t'ju tregojë se si të përdorni C++ në mënyrë efektive. Supozoj se tashmë jeni njohur me C++ si gjuhë programimi, dhe gjithashtu të ketë një përvojë me të. Unë ju ofroj udhëzime për përdorimin e kësaj gjuhe, ndjekja e të cilave do t'i bëjë programet tuaja të kuptueshme, të lehta për t'u mirëmbajtur, të lëvizshme, të zgjerueshme, efikase dhe të funksionojnë siç pritej.

Këshillat e sugjeruara mund të ndahen në dy kategori: strategjinë e përgjithshme dizajni dhe përdorim praktik konstruktet individuale gjuhësore. Diskutimi i çështjeve të dizajnit ka për qëllim t'ju ndihmojë të zgjidhni midis qasjeve të ndryshme për zgjidhjen e një problemi të veçantë në C++. Çfarë të zgjidhni: trashëgimi apo shabllone? Trashëgimi e hapur apo e mbyllur? Trashëgimi apo përbërje e mbyllur? Funksionet e anëtarëve apo funksionet e lira? Duke kaluar sipas vlerës apo referencës? Është e rëndësishme të merrni vendimin e duhur që në fillim, pasi pasojat e një zgjedhjeje të keqe mund të mos shfaqen derisa të jetë tepër vonë, dhe ribërja mund të jetë e vështirë, kërkon kohë dhe e kushtueshme.

Edhe kur e dini saktësisht se çfarë doni të bëni, marrja e rezultateve që dëshironi mund të jetë e vështirë. Çfarë lloj vlere duhet të kthejë operatori i caktimit? Kur duhet një destruktor të jetë virtual? Si sillet operatori i ri nëse nuk mund të gjejë memorie të mjaftueshme? Është jashtëzakonisht e rëndësishme të përpunohen detaje të tilla, sepse përndryshe pothuajse me siguri do të hasni në sjellje të papritura dhe madje të pashpjegueshme të programit. Ky libër do t'ju ndihmojë të shmangni situata të tilla.

Sigurisht, ky libër është i vështirë të përmendet. udhëzues i plotë në C++. Përkundrazi, është një koleksion i 55 këshillave (ose rregullave) të tyre për të përmirësuar programet dhe projektet tuaja. Çdo paragraf është pak a shumë i pavarur nga të tjerët, por shumica kanë referenca të kryqëzuara. Mënyra më e mirë për të lexuar këtë libër është të filloni me rregullin që ju intereson më shumë dhe më pas të ndiqni lidhjet për të parë se ku ju çojnë.

Ky libër gjithashtu nuk është një hyrje në C++. Në kapitullin 2, për shembull, unë flas për zbatimin e saktë të konstruktorëve, destruktorëve dhe operatorëve të caktimit, por supozoj se ju tashmë e dini se çfarë bëjnë këto funksione dhe si deklarohen ato. Ka shumë libra C++ mbi këtë temë.

Synimi kjo libra për të nxjerrë në pah aspekte të programimit C++ që shpesh anashkalohen. Libra të tjerë përshkruajnë pjesë të ndryshme të gjuhës. Ai gjithashtu përshkruan se si t'i kombinoni ato me njëri-tjetrin për të marrë programe efektive. Publikime të tjera flasin se si të merrni një program për të përpiluar. Dhe ky libër ka të bëjë me shmangien e problemeve që përpiluesi nuk mund t'i zbulojë.

Në të njëjtën kohë, ky libër është i kufizuar në standarde C++. Këtu përdoren vetëm ato veçori gjuhësore që përshkruhen në standardin zyrtar. Transportueshmëria është një çështje kyçe për këtë libër, kështu që nëse po kërkoni truket specifike për platformën, kërkoni diku tjetër.

As nuk do të gjeni Ungjillin e C++ në këtë libër, të vetmen mënyrë të sigurt për një program të përsosur C++. Çdo rregull është një rekomandim në një aspekt ose në një tjetër: si të gjeni një dizajn më të mirë, si të shmangni gabimet e zakonshme si të arrihet efikasiteti maksimal, por asnjë nga pikat nuk është universalisht e zbatueshme. Projektimi dhe zhvillimi i softuerit është një detyrë komplekse që ndikohet nga kufizimet hardware, sistemin operativ dhe aplikacionet, kështu që më e mira që mund të bëj është të imagjinoj rekomandimet për të përmirësuar cilësinë e programeve.

Nëse ndiqni sistematikisht të gjitha udhëzimet, nuk ka gjasa të hasni në grackat më të zakonshme të C++, por ka përjashtime nga çdo rregull. Kjo është arsyeja pse në çdo rregull jepen shpjegime. Ato janë pjesa më e rëndësishme e librit. Vetëm duke kuptuar se çfarë qëndron në themel të këtij apo atij rregulli, mund të vendosni se si përshtatet me programin tuaj me kufizimet e veta.

Mënyra më e mirë për të përdorur këtë libër është të kuptoni sekretet e sjelljes së C++, të kuptoni pse ai sillet ashtu siç sillet dhe të përdorni sjelljen e tij në avantazhin tuaj. Zbatimi i verbër në praktikë i të gjitha rregullave të mësipërme është krejtësisht i papërshtatshëm, por në të njëjtën kohë, nuk duhet vepruar pa arsye të veçanta në kundërshtim me këto këshilla.

Terminologjia

Ekziston një fjalor i vogël C++ me të cilin duhet të njihet çdo programues. Termat e mëposhtëm janë mjaft të rëndësishëm saqë ka kuptim të sigurohemi që t'i kuptojmë në të njëjtën mënyrë.

Njoftim(deklarata) i tregon përpiluesit emrin dhe llojin e diçkaje, duke lënë jashtë disa detaje. Reklamat duken kështu:


extern int x; // deklarimi i objektit

std::size_t numDigits(int number); // deklarata e funksionit

Widget i klasës; // deklarata e klasës

shabllon // deklarim shabllon

klasa GraphNode; // (Shih rregullin 42 për atë që është "emri i tipit".


Vini re se unë i referohem x-it të plotë si një "objekt" edhe pse është një variabël i një lloji të integruar. Disa njerëz nënkuptojnë vetëm variabla të tipit të përcaktuar nga përdoruesi me "objekte", por unë nuk jam një prej tyre. Gjithashtu vini re se funksioni numDigits() kthen llojin std::size_t, domethënë llojin size_t nga hapësira e emrave std. Kjo është hapësira e emrave që përmban pothuajse gjithçka nga Biblioteka Standarde e C++. Megjithatë, meqenëse biblioteka standarde C (më konkretisht, C89) mund të përdoret gjithashtu në një program C++, simbolet e trashëguara nga C (si p.sh. size_t) mund të ekzistojnë në konteksti global, brenda std, ose të dyja, në varësi të skedarëve të kokës që janë përfshirë me direktivën #include. Në këtë libër, supozoj se skedarët e kokës C++ përfshihen duke përdorur #include. Kjo është arsyeja pse unë përdor std::size_t dhe jo vetëm size_t. Kur përmend komponentët standardë të bibliotekës jashtë kodit të programit, zakonisht e heq referencën për std, duke supozuar se e dini se gjëra të tilla si size_t, vector dhe cout janë në hapësirën e emrave std. Në programet shembull, unë gjithmonë përfshij std, sepse përndryshe kodi nuk do të përpilohet.

Nga rruga, size_t është vetëm një pseudonim i përcaktuar nga typedef për disa lloje të panënshkruara që C++ përdor për të lloj te ndryshme numëruesit (për shembull, numri i karaktereve në vargjet char*, numri i elementeve në kontejnerët STL, etj.). Është gjithashtu lloji i pranuar nga funksionet e operatorit në vektorë, deques dhe vargje. Ne do ta ndjekim këtë konventë kur përcaktojmë funksionet tona të operatorit në Rregullin 3.

Çdo deklaratë funksioni e specifikon atë nënshkrimi, pra llojet e parametrave dhe vlera e kthyer. Mund të themi se nënshkrimi i një funksioni është lloji i tij. Kështu, nënshkrimi i funksionit numDigits është std::size_t(int), me fjalë të tjera, është "një funksion që merr një int dhe kthen std::size_t". Përkufizimi zyrtar Një "nënshkrim" në C++ nuk përfshin llojin e kthimit të një funksioni, por për qëllimet e këtij libri, do të jetë e përshtatshme për ne të supozojmë se është ende pjesë e nënshkrimit.

Përkufizimi(përkufizimi) i tregon përpiluesit detajet që janë hequr nga deklarata. Për një objekt, përkufizimi është vendi ku përpiluesi cakton memorie për të. Për një model funksioni ose funksioni, përkufizimi përmban trupin e funksionit. Përkufizimi i një modeli klase ose klase liston anëtarët e tij:


intx; // përcaktimi i objektit

std::size_t numDigits(int number) // përcaktimi i funksionit

( // (ky funksion kthen numrin

std::size_t shifraDeri Larg = 1; // numrat dhjetorë në parametrin e tij)

ndërsa((numri /= 10) != 0) ++shifraDeri Larg;

shifrat e kthimitDeri Larg;

Widget i klasës ( // përkufizimi i klasës

shabllon // përcaktim shabllon

GraphNode i klasës (


Inicializimi(inicializimi) është procesi i caktimit të një vlere fillestare për një objekt. Për objektet e llojeve të përcaktuara nga përdoruesi, inicializimi kryhet nga konstruktorët. Konstruktori i parazgjedhur(ndërtuesi i parazgjedhur) është një konstruktor që mund të thirret pa argumente. Një konstruktor i tillë ose nuk ka fare parametra, ose ka një vlerë të paracaktuar për çdo parametër:


A(); // konstruktori i paracaktuar

eksplicite B(int x = 0; bool b = true); // konstruktori i paracaktuar,

// fjala kyçe "e qartë"

eksplicite C(int x); // ky nuk është një konstruktor

// default


Konstruktorët e klasave B dhe C deklarohen me fjalën kyçe eksplicite. Kjo i pengon ato të përdoren për konvertime të tipit të nënkuptuar, megjithëse nuk i pengon ato të përdoren nëse konvertimi është specifikuar në mënyrë eksplicite:


void doSomething(B bObject); // Funksioni merr një objekt të tipit B

BbObj1; // objekt i tipit B

bëj Diçka (bObj1); // ok, B kalohet te doSomething

bObj(28); // ok, krijon B nga numri i plotë 28

// (parametri i paracaktuar bool është i vërtetë)

bëj Diçka (28); // gabim! bëj Diçka pranon B,

// jo int, dhe nuk ka asnjë të nënkuptuar

// konvertimi nga int në B

bëj Diçka (B(28)); // ok, përdoret konstruktori

// B për konvertimin e qartë (cast)

// int në B (shih rregullin 27 për informacion

// në lidhje me hedhjen e tipit)


Konstruktorët e deklaruar eksplicit përgjithësisht preferohen sepse parandalojnë përpiluesit të kryejnë konvertime të tipit të nënkuptuar (shpesh të padëshiruar). Nëse nuk ka një arsye të mirë për përdorimin e konstruktorëve në konvertimet e tipit të nënkuptuar, unë gjithmonë i deklaroj ato të qarta. Unë ju këshilloj t'i përmbaheni të njëjtit parim.

Vini re se në shembullin e mëparshëm, aktori është theksuar. Unë do të vazhdoj ta përdor këtë theksim për të theksuar rëndësinë e materialit të paraqitur. (Unë gjithashtu theksoj numrat e kapitujve, por kjo është vetëm sepse mendoj se duket bukur.)

konstruktor kopje(ndërtuesi i kopjes) përdoret për të inicializuar një objekt me vlerën e një objekti tjetër të të njëjtit lloj, dhe operatori i caktimit të kopjeve(operatori i caktimit të kopjes) përdoret për të kopjuar vlerën e një objekti në një tjetër - të të njëjtit lloj:


widget(); // konstruktori i paracaktuar

Widget(konst Widget&rhs); // konstruktor kopje

Widget& operator=(konst Widget& rhs); // Operatori i caktimit të kopjes

Widget w1; // thirrni konstruktorin e paracaktuar

Widget w2(w1); // thirrje konstruktor kopje

w1 = w2; // operatori i caktimit të thirrjeve

// kopje


Kini kujdes kur shihni një konstrukt të ngjashëm me detyrën, sepse sintaksa "=" mund të përdoret gjithashtu për të thirrur një konstruktor kopjimi:


Widget w3 = w2; // thirrni konstruktorin e kopjes!


Për fat të mirë, një konstruktor kopjimi është i lehtë për t'u dalluar nga një detyrë. Nëse përcaktohet një objekt i ri (si w3 në fjalinë e fundit), atëherë duhet të thirret konstruktori, ai nuk mund të jetë një caktim. Nëse nuk krijohet asnjë objekt i ri (si në "w1=w2"), atëherë nuk aplikohet asnjë konstruktor dhe është një caktim.

Konstruktori i kopjimit është një veçori veçanërisht e rëndësishme sepse përcakton se si një objekt kalohet sipas vlerës. Për shembull, merrni parasysh fragmentin e mëposhtëm:


bool kaAcceptableQuality (Widget w);

nëse (ka Cilësi të pranueshme (aWidget)) ...


Parametri w i kalohet funksionit hasAcceptableQuality sipas vlerës, kështu që në thirrjen e shembullit të mësipërm, aWidget kopjohet në w. Kopjimi bëhet nga konstruktori i kopjes nga klasa Widget. Në përgjithësi, kaloni sipas vlerës do të thotë duke thirrur konstruktorin e kopjes. (Por në mënyrë rigoroze, kalimi i llojeve të personalizuara sipas vlerës është ide e keqe. Kalimi duke iu referuar një konstante është zakonisht më i miri, shihni Pikën 20 për detaje.)

STL– Biblioteka standarde e shablloneve është pjesa e bibliotekës standarde që merret me kontejnerët (d.m.th. vektori, lista, grupi, harta, etj.), përsëritësit (d.m.th. vector::iterator, set::iterator, etj.) etj.) , algoritmet (d.m.th. për_secilin, gjeni, rendit, etj.) dhe të gjithë funksionalitetet përkatëse. Përdoret gjerësisht objektet e funksionit(objekte funksioni), pra objekte që sillen si funksione. Objekte të tilla përfaqësohen nga klasa në të cilat operatori i thirrjes () është i mbingarkuar. Nëse nuk jeni të njohur me STL-në, do t'ju duhet një udhëzues i mirë për këtë temë përveç këtij libri, sepse STL është aq i dobishëm sa që do të ishte e pafalshme të mos përfitoni prej tij. Duhet vetëm të filloni të punoni me të, dhe ju vetë do ta ndjeni atë.

Programuesit që vijnë në C++ nga gjuhë si Java ose C# mund ta gjejnë konceptin e sjellje e papërcaktuar. Për arsye të ndryshme, sjellja e disa konstrukteve në C++ është vërtet e papërcaktuar: nuk mund të parashikoni me siguri se çfarë do të ndodhë në kohën e ekzekutimit. Këtu janë dy shembuj të këtij lloji:


int *p = 0; // p është një tregues null

emri char = "Daria" // emri është një grup me gjatësi 6 (mos harroni

// përfundimi null!)

char c = emri; // duke specifikuar një indeks të pasaktë të grupit

// krijon sjellje të papërcaktuar


Për të theksuar se rezultatet e sjelljes së papërcaktuar janë të paparashikueshme dhe mund të jenë mjaft të pakëndshme, programuesit me përvojë të C++ shpesh thonë se programet me sjellje të papërcaktuar mund të fshijnë përmbajtjen e një hard disk. Është e vërtetë që një program i tillë ndoshta fshij tuajin HDD, por mund të mos e bëjë këtë. Ka më shumë gjasa që të sillet ndryshe: ndonjëherë do të funksionojë mirë, ndonjëherë do të rrëzohet dhe ndonjëherë do të japë thjesht rezultate të gabuara. Programuesit e mençur C++ ndjekin rregullin e shmangies së sjelljes së papërcaktuar. Në këtë libër, në shumë vende, unë tregoj se si ta bëjmë këtë.

Një term tjetër që mund të ngatërrojë programuesit që vijnë nga gjuhë të tjera është ndërfaqe. Në Java dhe. Në gjuhët e përputhshme me NET, ndërfaqet janë pjesë e gjuhës, por C++ nuk ka asgjë të tillë, megjithëse pika 31 diskuton disa përafrime. Kur përdor termin "ndërfaqe" zakonisht nënkuptoj nënshkrime funksioni, anëtarë të aksesueshëm të klasës ("ndërfaqe publike", "ndërfaqe e mbrojtur", " ndërfaqe private”) ose shprehjet e lejuara si parametra tipi për shabllonet (shih Pikën 41). Kjo do të thotë, me ndërfaqe, unë kuptoj konceptin e përgjithshëm të dizajnit.

koncept klientështë diçka ose dikush që përdor kodin që ju shkruani (zakonisht nëpërmjet ndërfaqeve). Kështu, për shembull, klientët e një funksioni janë përdoruesit e tij: pjesët e kodit që thërrasin funksionin (ose marrin adresën e tij), si dhe njerëzit që shkruajnë dhe ruajnë një kod të tillë. Klientët e një klase ose modeli janë pjesët e programit që përdorin klasën ose shabllonin, si dhe programuesit që shkruajnë ose mirëmbajnë ato pjesë. Kur bëhet fjalë për klientët, zakonisht nënkuptoj programuesit, sepse ata janë ata që mund të mashtrohen ose të jenë të pakënaqur me një ndërfaqe të dizajnuar keq. Kodi që ata shkruajnë nuk e ka atë lloj emocioni.

Ndoshta nuk jeni mësuar të mendoni për klientët, por unë do të përpiqem t'ju bind për nevojën për t'ua bërë jetën sa më të lehtë atyre. Në fund të fundit, ju vetë jeni një klient i softuerit që është zhvilluar nga dikush tjetër. Në fund të fundit, do të dëshironit që autorët e tij t'ua lehtësonin punën? Për më tepër, herët a vonë do ta gjeni veten në një pozicion ku ju vetë do të bëheni klient i kodit tuaj (d.m.th., do të përdorni kodin që shkruani), dhe më pas vlerësoni që kur dizajnoni ndërfaqe, duhet të mbani në mendje interesat e klientëve.

Në këtë libër, unë shpesh tërheq vëmendjen për dallimin midis funksioneve dhe modeleve të funksioneve, dhe midis klasave dhe modeleve të klasave. Kjo nuk është rastësi, sepse ajo që është e vërtetë për një është shpesh e vërtetë për një tjetër. Në situatat kur nuk është kështu, unë bëj një dallim midis klasave, funksioneve dhe modeleve nga të cilat rrjedhin klasat dhe funksionet.

Konventat e emërtimit

Jam përpjekur të zgjedh emra kuptimplotë për objekte, klasa, funksione, shabllone e kështu me radhë, por semantika e disa prej emrave që kam gjetur mund të mos jetë e qartë për ju. Për shembull, unë shpesh përdor emrat lhs dhe rhs për parametrat. Kjo i referohet përkatësisht "anës së majtë" (ana e majtë) dhe "ana e djathtë" (ana e djathtë). Këta emra zakonisht përdoren në funksionet që implementojnë operatorë binarë, pra operator== dhe operator*. Për shembull, nëse a dhe b janë objekte që përfaqësojnë numra racional, dhe nëse objektet racionale mund të shumëzohen duke përdorur funksionin jo-anëtar operator*() (një rast i ngjashëm përshkruhet në pikën 24), atëherë shprehja



është e barabartë me një thirrje funksioni:


operator*(a, b);


Në pikën 24, unë deklaroj operatorin* si ky:


operator konst Racional*(konst Racional& lhs, konst Racional& rhs);


Siç mund ta shihni, operandi i majtë - a - brenda funksionit quhet lhs, dhe i djathti - b - rhs.

Për funksionet anëtare, argumenti në anën e majtë të operatorit përfaqësohet nga ky tregues, dhe të vetmin parametër të mbetur ndonjëherë e quaj rhs. Ju mund ta keni vënë re këtë në deklaratën e disa prej funksioneve të anëtarëve të klasës Widget në shembujt e mësipërm. "Widget" nuk do të thotë asgjë. Është thjesht një emër që unë ndonjëherë e përdor për t'i dhënë një klasë shembull një emër. Nuk ka të bëjë me kontrollet (widget) të përdorura në ndërfaqet grafike(GUI).

Shpesh unë emërtoj tregues sipas konventës që një tregues për një objekt të tipit T quhet pt ("tregues në T"). Ketu jane disa shembuj:


Widget *pw; // pw = treguesi në Widget

Aeroplan *pa; // pa = treguesi në aeroplan

klasa GameCharacter;

Karakteri i lojës *pgc; // pgc = tregues për GameCharacter


Një konventë e ngjashme vlen për lidhjet: rw mund të jetë një lidhje Widget dhe ra mund të jetë një lidhje Aeroplani.

Ndonjëherë përdor emrin mf për të emërtuar një funksion anëtar.

Multithreading

Në vetë gjuhën C++, nuk ekziston koncepti i thread-eve (threads), dhe në të vërtetë i ndonjë mekanizmi për ekzekutim paralel. E njëjta gjë vlen edhe për bibliotekën standarde C++. Me fjalë të tjera, nga pikëpamja e C++, programet multithreaded nuk ekzistojnë.

Megjithatë, ata janë. Edhe pse në këtë libër do të flas kryesisht për C++ standard dhe portativ, është e pamundur të injorohet fakti që siguria e fijeve është një kërkesë me të cilën përballen shumë programues. Duke e njohur këtë konflikt midis standardit C++ dhe realitetit, do të shënoj raste kur konstruktet në fjalë mund të shkaktojnë probleme kur ekzekutohen në një mjedis me shumë fije. Mos mendoni se ky libër do t'ju mësojë se si të programoni C++ me shumë fije. Aspak. Kam shqyrtuar kryesisht aplikacione me një fije, por nuk e kam injoruar ekzistencën e multithreading-ut dhe jam përpjekur të vë në dukje rastet kur programuesit që shkruajnë programe multithreaded duhet të ndjekin me kujdes këshillat e mia.

Nëse nuk jeni të njohur me konceptin e multithreading dhe nuk jeni të interesuar për këtë temë, atëherë mund të shpërfillni shënimet që lidhen me të. Përndryshe, mbani në mend se komentet e mia nuk janë gjë tjetër veçse një sugjerim modest i asaj që duhet të dini nëse do të përdorni C++ për të shkruar programe me shumë fije.

Bibliotekat TR1 dhe Boost

Ju do të shihni referenca për bibliotekat TR1 dhe Boost përgjatë këtij libri. Secila prej tyre ka një rregull të veçantë (54 - TR1 dhe 55 - Boost), por, për fat të keq, ato janë në fund të librit. Ju mund t'i lexoni ato tani nëse dëshironi, por nëse preferoni ta lexoni librin me radhë dhe jo nga fundi, shënimet e mëposhtme do t'ju ndihmojnë të kuptoni se çfarë është në rrezik:

TR1 ("Raporti Teknik 1") është një specifikim për funksionalitetin e ri të shtuar bibliotekë standarde C++. Ai është i paketuar në shabllone dhe funksione të reja të klasave për të zbatuar tabela hash, tregues inteligjentë të numëruar me referencë, shprehje të rregullta dhe më shumë. Të gjithë komponentët TR1 janë në hapësirën e emrave tr1, e cila është e vendosur në hapësirën e emrave std.

Boost është një organizatë dhe faqe interneti (http://boost.org) që ofron biblioteka portative C++ me burim të hapur dhe të rishikuara mirë. Kodi i burimit. Pjesa më e madhe e TR1 bazohet në punën e bërë nga Boost, dhe derisa shitësit e përpiluesve të përfshijnë TR1 në shpërndarjet C++, faqja e internetit e Boost do të vazhdojë të jetë burimi kryesor i zbatimeve të TR1 për zhvilluesit. Boost ofron më shumë sesa ajo që përfshihet në TR1, por është mirë të dini për të gjithsesi.

Mësohuni me C++

Pavarësisht përvojës së programimit, duhet pak kohë për t'u qetësuar me C++. Është një gjuhë e fuqishme me një shumë gamë të gjerë mundësitë, por për t'i përdorur ato në mënyrë efektive, duhet të ndryshoni pak mënyrën tuaj të të menduarit. Ky libër është krijuar për t'ju ndihmuar të bëni pikërisht këtë, por disa pyetje janë më të rëndësishme se të tjerat dhe ky kapitull ka të bëjë me gjërat më të rëndësishme.

Rregulli 1: Trajtojeni C++ si një konglomerat gjuhësh

Në fillim, C++ ishte vetëm një gjuhë C me disa veçori të orientuara drejt objektit. Edhe emri origjinal i C++ ("C me klasa") pasqyron këtë lidhje.

Ndërsa gjuha është pjekur, ajo është rritur dhe evoluar duke përfshirë ide dhe strategji programimi që shkojnë përtej C me klasa. Përjashtimet kërkonin një qasje të ndryshme për strukturimin e funksioneve (shih rregullin 29). Modelet kanë ndryshuar mënyrën se si ne mendojmë për dizajnin e softuerit (shih Pikën 41), dhe STL ka përcaktuar një qasje ndaj shtrirjes që askush nuk mund ta imagjinonte më parë.

Sot gjuha është C++ programimi me paradigma të shumta, mbështetje procedurale, të orientuar nga objekti, funksional, gjenerik dhe metaprogramim. Kjo fuqi dhe fleksibilitet e bën C++ një mjet të pakrahasueshëm, por mund të jetë konfuz. Çdo rekomandim për aplikimi korrekt» ka përjashtime. Si të gjesh kuptimin në një gjuhë të tillë?

Është më mirë të mendosh për C++ jo si një gjuhë, por si një konglomerat gjuhësh të lidhura. Në një nëngjuhë të vetme, rregullat janë mjaft të thjeshta, të kuptueshme dhe të lehta për t'u mbajtur mend. Megjithatë, ndërsa kaloni nga një nëngjuhë në tjetrën, rregullat mund të ndryshojnë. Për të kuptuar C++, duhet të njihni nëngjuhët e tij kryesore. Për fat të mirë, ka vetëm katër prej tyre:

C. Në thelbin e tij, C++ bazohet ende në C. Blloqet, klauzolat, paraprocesorin, llojet e integruara të të dhënave, vargjet, treguesit, e kështu me radhë të gjitha vijnë nga C. Në shumë raste, C++ ofron mekanizma më të avancuar për zgjidhjen e problemeve të caktuara. sesa C (për shembull, shih Rregullin 2 - Alternativa e Paraprocesorit dhe 13 - Përdorimi i Objekteve për Menaxhimin e Burimeve), por kur të filloni të punoni me pjesën e C++ që ka homologë në C, do të kuptoni se rregullat e programimit efikas reflektojnë natyra më e kufizuar e gjuhës C: pa shkronja të egra, pa përjashtime, pa mbingarkesë, etj.

C++ i orientuar nga objekti. Kjo pjesë e C++ përfaqëson atë që ishte "C me klasa", duke përfshirë konstruktorët dhe destruktorët, kapsulimin, trashëgiminë, polimorfizmin, funksionet virtuale(lidhje dinamike), etj. Kjo është pjesa e C++ që shumica zbatohen rregullat klasike të dizajnit të orientuar nga objekti.

C++ me shabllone. Kjo pjesë e C++ quhet programim gjenerik dhe shumica e programuesve dinë pak për të. Modelet tani përshkojnë C++ nga lart poshtë, dhe tashmë është një shenjë e praktikës së mirë programuese përfshirja e konstruksioneve që janë të paimagjinueshme pa shabllone (për shembull, shih Pikën 46 mbi konvertimin e tipit në thirrjet në funksionet e shabllonit). Në fakt, shabllonet, për shkak të fuqisë së tyre, kanë krijuar një paradigmë programimi krejtësisht të re: metaprogramimi shabllon(metaprogramimi i shabllonit - TMP). Artikulli 48 ofron një përmbledhje të TMP-së, por nëse nuk jeni një fanatik i guximshëm i shablloneve, nuk keni arsye ta mendoni shumë atë. TMP nuk është një nga teknikat më të zakonshme të programimit C++.

STL. STL është, sigurisht, një bibliotekë shabllonesh, por shumë e specializuar. Konventat e tij për kontejnerët, përsëritësit, algoritmet dhe objektet e funksionit luajnë mirë së bashku, por shabllonet dhe bibliotekat mund të ndërtohen ndryshe. Kur punoni me bibliotekën STL, duhet të ndiqni konventat e saj.

Mbani parasysh këto katër nëngjuhë dhe mos u habitni nëse e gjeni veten në një situatë ku konsideratat e efikasitetit kërkojnë që ju të ndryshoni strategjinë tuaj kur kaloni nga një nëngjuhë në tjetrën. Për shembull, për llojet e integruara (në stilin C), kalimi i parametrave sipas vlerës në rast i përgjithshëmështë më efikas se kalimi me referencë, por nëse jeni duke programuar në një stil të orientuar nga objekti, prania e konstruktorëve dhe destruktorëve të përcaktuar nga përdoruesi zakonisht e bën kalimin duke iu referuar një konstante më efikase. Kjo është veçanërisht e vërtetë në nëngjuhën "C++ me shabllone", sepse atje zakonisht nuk e dini as paraprakisht llojin e objekteve me të cilat keni të bëni. Por tani ju keni kaluar në përdorimin e STL, dhe përsëri rregulli i vjetër C për kalimin me vlerë hyn në lojë, sepse përsëritësit dhe objektet e funksionit janë modeluar në termat e treguesve C. (Shihni Rregullën 20 për më shumë mbi zgjedhjen e mënyrës së kalimit parametrat.)

Kështu, C++ nuk është një gjuhë homogjene me një grup të vetëm rregullash. Është një konglomerat nëngjuhësh, secila me konventat e veta. Nëse i mbani parasysh këto nëngjuhë, do të zbuloni se C++ është shumë më e lehtë për t'u kuptuar.

Gjërat për të mbajtur mend

Rregullat për programim efektiv ndryshojnë në varësi të pjesës së C++ që përdorni.

Rregulli 2: Preferoni const, enum dhe inline mbi #define

Ky rregull do të quhej më mirë "Përpiluesi mbi paraprocesor" sepse #define shpesh nuk konsiderohet fare një gjuhë C++. Këtu qëndron problemi. Konsideroni një shembull të thjeshtë; provoni të shkruani diçka si:


#define ASPECT_RATIO 1.653


Emri simbolik ASPECT_RATIO mund të mbetet i panjohur për kompajlerin ose të hiqet nga paraprocesori përpara se kodi të përpunohet nga përpiluesi. Nëse kjo ndodh, atëherë emri ASPECT_RATIO nuk do të futet në tabelën e simboleve. Prandaj, gjatë përpilimit, do të merrni një gabim (vlera 1.653 do të përmendet në mesazhin e gabimit, jo ASPECT_RATIO). Kjo do të shkaktojë konfuzion. Nëse emri ASPECT_RATIO është përcaktuar në një skedar kokë që nuk e keni shkruar, atëherë nuk do ta dini fare se nga erdhi vlera 1.653 dhe do të kaloni shumë kohë duke kërkuar një përgjigje. I njëjti problem mund të ndodhë edhe gjatë korrigjimit, sepse emri që zgjidhni nuk do të jetë në tabelën e simboleve.

Zgjidhja është zëvendësimi i makro me një konstante:


konst dyfishtë Raporti i Aspektit = 1.653; // emrat e shkruar shkronjat e mëdha,

// zakonisht përdoret për makro,

// kështu që ne vendosëm ta ndryshojmë atë


Duke qenë një konstante gjuhësore, AspectRatio është i dukshëm për përpiluesin dhe vendoset natyrshëm në tabelën e simboleve. Përveç kësaj, përdorimi i një konstante me pikë lundruese (si në këtë shembull) gjeneron kod më kompakt sesa përdorimi i #define. Fakti është se paraprocesori, duke zëvendësuar verbërisht vlerën 1.653 në vend të makros ASPECT_RATIO, krijon shumë kopje të 1.653 në kodin e objektit, ndërsa përdorimi i një konstante nuk do të gjenerojë kurrë më shumë se një kopje të kësaj vlere.

Kur zëvendësoni # përcaktojnë konstante dy gjëra për të mbajtur mend Raste të veçanta. E para ka të bëjë me tregues të vazhdueshëm. Sepse përkufizimet konstante zakonisht vendosen në skedarët e kokës (ku ato aksesohen nga shumë të ndryshëm skedarët burimor), është e rëndësishme që tregues u deklarua me fjalën kyçe const, përveç deklaratës konst të asaj që tregon. Për shembull, për të deklaruar një varg konstant të tipit char* në një skedar header, duhet të shkruhet fjala const. dy herë:


const char * const authorName = "Scott Meyers";


Për më shumë mbi natyrën dhe përdorimet e fjalës const, veçanërisht në lidhje me treguesit, shih Pikën 3. Por tani për tani, ia vlen të kujtojmë se objektet e tipit string zakonisht preferohen ndaj paraardhësve të tyre - vargjet e tipit char *, kështu që është më mirë të përkufizosh emrin e autorit si kjo:


const std::string Emri i autorit("Scott Meyers");


Vërejtja e dytë ka të bëjë me konstantet e deklaruara si pjesë e një klase. Për të përfshirë një konstante në një klasë, ju duhet ta bëni atë një anëtar të klasës dhe për të siguruar që ka vetëm një kopje të konstantës, duhet ta bëni atë statike anëtar:


classGamePlayer(

static const int NumTurns = 5; // deklarim konstant

pikët int; // duke përdorur një konstante


Ajo që shihni më lart është shpallje NumTurns, jo përkufizimi i tij. C++ normalisht kërkon që ju të jepni një përkufizim për çdo gjë që përdorni, por konstantet e deklaruara në një klasë që janë statike dhe kanë një lloj të integruar (d.m.th. numër i plotë, karakter, boolean) janë përjashtim nga rregulli. Për sa kohë që nuk po përpiqeni të merrni adresën e një konstante të tillë, mund ta deklaroni dhe përdorni pa dhënë një përkufizim. Nëse ju duhet të merrni adresën, ose nëse përpiluesi juaj insiston të ketë një përkufizim, mund të shkruani diçka si kjo:


const int GamePlayer::NumTurns; // definoni NumTurns; Shikoni më poshtë,

// pse vlera nuk është e specifikuar


Vendoseni këtë kod në skedarin e zbatimit, jo në skedarin e kokës. Meqenëse vlera fillestare e një konstante të klasës jepet aty ku deklarohet (d.m.th., NumTurns inicializohet në 5 kur deklarohet), nuk ka nevojë të specifikohet një vlerë fillestare në pikën e përcaktimit.

Vini re, meqë ra fjala, se nuk është e mundur të deklarohet një konstante në një klasë me #define, sepse #define nuk është scope-aware. Pasi të përcaktohet një makro, ajo mbetet në fuqi për pjesën tjetër të kodit të përpiluar (përveç nëse #undef shfaqet diku më poshtë). Kjo do të thotë se direktiva #define jo vetëm që është e pazbatueshme për deklarimin e konstantave në një klasë, por nuk mund të përdoret për të siguruar asnjë lloj kapsulimi fare, domethënë është e pamundur t'i jepet kuptim shprehjes "private #define". Në të njëjtën kohë, anëtarët e të dhënave konstante mund të kapsulohen, NumTurns është një shembull.

Përpiluesit më të vjetër mund të mos mbështesin sintaksën e treguar më sipër sepse versionet e mëparshme të gjuhës nuk lejonin që vlerat e anëtarëve të klasës statike të vendoseshin në kohën e deklarimit. Për më tepër, inicializimi në një klasë lejohej vetëm për llojet e numrave të plotë dhe për konstantet. Nëse sintaksa e mësipërme nuk funksionon, atëherë vlera fillestare duhet të specifikohet në përkufizim:


Kostoja e klasës (

konst statik i dyfishtë FudgeFactor; // deklarim statik konstante

... // class - vendoset në skedarin e kokës

konst dyfish // përcaktim statik i konstantës

Kostoja::FadgeFactor = 1,35; // class - vendoset në skedarin e zbatimit


Zakonisht nuk kërkohet asgjë më shumë. Përjashtimi i vetëm është kur nevojitet një konstante për të përpiluar klasën. Për shembull, kur deklaron një grup GamePlayer::scores, përpiluesi duhet të dijë madhësinë e grupit. Për të punuar me një përpilues që gabimisht ndalon inicializimin e konstantave të numrave të plotë statikë brenda një klase, mund të përdorni një teknikë të njohur si "mashtrimi i enum". Ai mbështetet në faktin se variablat e numëruar mund të përdoren aty ku priten vlerat int, kështu që GamePlayer mund të përcaktohet si kjo:


classGamePlayer(

enum(NumTurns = 5 ); // "mashtrim i numërimit" - bën nga

// Karakteri NumTurns me vlerë 5

pikët int; // mirë


Kjo teknikë ia vlen të njihet për disa arsye. Së pari, sjellja e "mashtrimit të enum" është në disa aspekte më shumë si një #define sesa një konstante, dhe ndonjëherë kjo është pikërisht ajo që dëshironi. Për shembull, ju mund të merrni adresën e një konstante, por nuk mund të merrni adresën e një enum, ashtu siç nuk mund të merrni adresën e #define. Nëse dëshironi të parandaloni marrjen e një adrese ose një referencë për një konstante të numrit të plotë, atëherë përdorimi i enum është një mënyrë e mirë për të vendosur një kufizim të tillë. (Shih artikullin 18 për më shumë mbi mbështetjen e kufizimeve të projektimit me teknikat e kodimit.) Gjithashtu, ndërsa përpiluesit e mirë nuk ndajnë memorie për objektet konst të llojeve të numrave të plotë (përveç nëse krijoni një tregues ose referencë objekti), përpiluesit më pak të sofistikuar mund ta bëjnë këtë, dhe ju mund të mos dëshironi. Ashtu si #define, enums nuk do të shkaktojnë kurrë këtë lloj shpërndarjeje të padëshiruar të memories.

Arsyeja e dytë për të ditur për "mashtrimin e numërimit" është thjesht pragmatike. Përdoret në shumë programe, kështu që ju duhet të jeni në gjendje ta njihni këtë truk kur ta hasni. Në përgjithësi, ky truk është një teknikë themelore e përdorur në metaprogramimin e shablloneve (shih Pikën 48).

Le të kthehemi te paraprocesori. Një tjetër keqpërdorim i zakonshëm i direktivës #define është krijimi i makrove që duken si funksione, por që nuk janë të ngarkuara me shpenzimet e përgjithshme të funksioneve të thirrjes. Më poshtë është një makro që thërret disa funksione f me një argument të barabartë me maksimumin e dy vlerave:


// quaj f, duke e kaluar atë maksimumin e a dhe b

#define CALL_WITH_MAX(a,b) f((a) > (b) ? (a) : (b))


Ka kaq shumë të meta në këtë linjë sa që nuk është as plotësisht e qartë se ku të fillohet.

Sa herë që shkruani një makro si kjo, duhet të mbani mend se të gjitha argumentet duhet të mbyllen në kllapa. Përndryshe rrezikon të futesh në telashe kur dikush e quan me një shprehje si argument. Por edhe nëse bëni gjithçka siç duhet, shikoni se çfarë gjërash të çuditshme mund të ndodhin:


int a = 5, b = 0;

THIRRJE_ME_MAX(++a, b); // a shtohet dy herë

THIRRJE_ME_MAX(++a, b+10); // a shtohet një herë


Ajo që ndodh brenda max varet nga ajo me çfarë po krahasohet!

Për fat të mirë, nuk duhet të duroni sjelljen që kundërshton kaq shumë logjikën. Ekziston një metodë që ju lejon të arrini të njëjtin efikasitet si përdorimi i paraprocesorit. Por në të njëjtën kohë, ai siguron sjellje të parashikueshme dhe kontroll të llojeve të argumenteve (që është tipike për funksionet e zakonshme). Ky rezultat arrihet duke përdorur shabllonin e funksionit inline (shih artikullin 30):


inline void callWithMax (konst T& a, const T& b) // Meqenëse nuk e dimë

( // çfarë është T, atëherë kalojmë

) // shih paragrafin 20


Ky shabllon gjeneron një familje të tërë funksionesh, secila prej të cilave merr dy argumente të të njëjtit lloj dhe thërret f me më të madhin prej tyre. Nuk ka nevojë për vendosjen e parametrave në kllapa brenda trupit të funksionit, nuk ka nevojë të shqetësoheni për vlerësime të shumëfishta të parametrave, etj. Për më tepër, duke qenë se callWithMax është një funksion real, ai i nënshtrohet rregullave të fushëveprimit dhe kontrollit të aksesit. Për shembull, mund të flisni për një funksion të integruar që është një anëtar privat i një klase. Është e pamundur të përshkruhet diçka e tillë duke përdorur një makro.

Prania e const, enum dhe inline redukton në mënyrë drastike nevojën për një paraprocesor (veçanërisht me #define), por nuk e eliminon plotësisht atë. Direktiva #include mbetet thelbësore dhe #ifdef/#ifndef vazhdojnë të luajnë një rol të rëndësishëm në kontrollin e përpilimit. Nuk është ende koha për të braktisur paraprocesorin, por padyshim ia vlen të merret parasysh se si të shpëtojmë prej tij në të ardhmen.

Gjërat për të mbajtur mend

Për konstante të thjeshta, direktiva #define duhet të preferojë objektet const dhe enums.

Në vend që të imitoni makrot e përcaktuara me #define, është më mirë të përdorni funksione të integruara.

Rregulli 3: Përdorni konst kudo që të jetë e mundur

E mira e modifikuesit konst është se ai imponon një kufizim të caktuar semantik: objekti i dhënë nuk duhet të modifikohet dhe përpiluesi do ta zbatojë atë kufizim. const ju lejon t'i tregoni përpiluesit dhe programuesve se një vlerë e caktuar duhet të mbetet e pandryshuar. Në të gjitha rastet e tilla, ju duhet ta tregoni këtë në mënyrë eksplicite, duke i kërkuar përpiluesit që t'ju ndihmojë dhe në këtë mënyrë të siguroheni që kufizimi të mos shkelet.


Kjo sintaksë nuk është aq e frikshme sa mund të duket. Nëse fjala const shfaqet në të majtë të yllit, ajo ku tregon treguesi është const; nëse në të djathtë, atëherë vetë treguesi është konst. Së fundi, nëse fjala const shfaqet në të dyja anët, atëherë të dyja janë konstante.

Shënime

Ekziston një përkthim rusisht: Stema Sutter. Zgjidhja e problemeve komplekse në C++. Shtëpia Botuese Williams, 2002 (Shënim i botimit shkencor).

Ekziston një përkthim rusisht: Modelet e dizajnit. Shën Petersburg: Peter (Përafërsisht botim shkencor).

Fundi i provës falas.

  • Faqet:
    , ,
  • Reagime për edicionin e tretë
    Përdorimi efektiv i C++

    libër nga Scott Meyers Duke përdorur C++ në mënyrë efektive, botimi i tretëështë përqendrimi i përvojës së programimit - përvoja që pa të do t'ju kishte ardhur me një çmim të lartë. Ky libër është një burim i shkëlqyer që ia rekomandoj kujtdo që shkruan C++ në mënyrë profesionale.

    Peter Dulimov, ME, Inxhinier, Njësia e Vlerësimit dhe Kërkimit NAVSYSCOM, Australi

    Edicioni i tretë mbetet libri më i mirë se si të bashkohen të gjitha pjesët e C++ për të krijuar programe efikase dhe të qëndrueshme nga brenda. Nëse pretendoni të jeni programues C++, duhet ta lexoni.

    Eric Nagler, konsulent, lektor dhe autor i Learning C++

    Botimi i parë i këtij libri ishte një nga një numër i vogël (shumë i paktë) librash që kanë përmirësuar vërtet nivelin tim si një zhvillues profesionist softuerësh. Ashtu si librat e tjerë të kësaj serie, ai ishte praktik dhe i lehtë për t'u lexuar, por përmbante edhe shumë këshilla të rëndësishme. "Përdorimi efektiv C++", botimi i tretë, vazhdon këtë traditë. C++ është një gjuhë programimi shumë e fuqishme. Nëse C ju jep një litar për t'u ngjitur në majë të një mali, atëherë C++ është një dyqan plot me lloj-lloj njerëzish që janë të gatshëm t'ju ndihmojnë të lidhni nyjet në atë litar. Zotërimi i materialit në këtë libër do të rrisë padyshim aftësinë tuaj për të përdorur C++ në mënyrë efektive dhe për të mos vdekur nga tendosja.

    Jack W. Reeves, CEO i Bleading Edge Software Technologies

    Çdo zhvilluesi i ri që bashkohet me ekipin tim i jepet menjëherë detyra për të lexuar këtë libër.

    Michael Lanzetta, inxhinier kryesor i softuerit

    E lexova edicionin e parë të Efektive C++ rreth 9 vjet më parë dhe shpejt u bë një nga librat e mi të preferuar në C++. Sipas mendimit tim, përdorimi efektiv i C++ Edicioni i 3-të mbetet një lexim i domosdoshëm për këdo që dëshiron të programojë në mënyrë efektive në C++. Ne do të jetojmë në një botë më të mirë nëse programuesit e C++ lexojnë këtë libër përpara se të shkruajnë rreshtin e parë të kodit profesional.

    Danny Rabbani, Inxhinier Softuerësh

    Edicioni i parë i Përdorimi efektiv i C++ nga Scott Meyers më erdhi kur isha një programues i zakonshëm dhe u përpoqa shumë për të bërë punën më të mirë që më ishte caktuar. Dhe ishte një shpëtimtar! Kam zbuluar se këshilla e Meyers është praktike dhe efektive, se ajo jep 100% atë që premton. Edicioni i tretë ju ndihmon të aplikoni C++ në projektet serioze të softuerit të sotëm duke ofruar informacion rreth veglave dhe veçorive më të fundit të gjuhës. Isha i kënaqur kur zbulova se mund të gjeja shumë gjëra të reja dhe interesante për veten time në botimin e tretë të një libri që mendoja se e njihja shumë mirë.

    Michael Topic, Menaxher Programi Teknik

    Ky është një udhëzues autoritar nga Scott Meyers, guru i C++, për këdo që dëshiron të përdorë C++ në mënyrë të sigurt dhe efikase, ose që po kalon në C++ nga çdo gjuhë tjetër e orientuar nga objekti. Ky libër përmban informacione të vlefshme të paraqitura në një stil të qartë, konciz, argëtues dhe depërtues.

    Siddhartha Karan Singh, Zhvillues i Softuerit

    Faleminderit

    Përdorimi efektiv i C++ ka qenë rreth 15 vjet, dhe unë fillova të mësoj C++ rreth 5 vjet përpara se ta shkruaja. Kështu, puna për këtë projekt ka rreth 20 vjet që po vazhdon. Gjatë kësaj kohe, kam marrë urime, komente, korrigjime dhe ndonjëherë vëzhgime mahnitëse nga qindra (mijëra?) njerëz. Secili prej tyre ndihmoi në zhvillimin e "Përdorimi i C++ në mënyrë efektive". Unë u jam mirënjohës të gjithëve.

    Unë hoqa dorë nga përpjekjet për të kujtuar se ku dhe çfarë kam mësuar vetë shumë kohë më parë, por nuk mund të mos përmend një burim sepse e përdor atë gjatë gjithë kohës. Këto janë grupet e lajmeve Usenet, veçanërisht comp.lang.c++.moderated dhe comp.std.c++. Shumë nga rregullat në këtë libër (ndoshta shumica) u krijuan si rezultat i të menduarit rreth ideve teknike të diskutuara në këto grupe.

    Steve Dewhurst më ndihmoi në përzgjedhjen e materialit të ri për botimin e tretë të librit. Në pikën 11, ideja e zbatimit të operatorit= me kopjim dhe shkëmbim është marrë nga shënimet e Herb Sutter, veçanërisht nga numri 13 i librit të tij Exceptional C++ (Addison-Wesley, 2000). Ideja e marrjes së një burimi si një inicializim (Rregulli 13) vjen nga Gjuha e Programimit C++ (Addison-Wesley, 2002) nga Bjarne Stroustrup. Ideja e rregullit 17 është marrë nga seksioni "Praktikat më të mira" të faqes së internetit Boost shared_ptr (http:// boost.org/libs/smart_ptr/shared_ptr.htm#BestPractices) dhe është përpunuar bazuar në materialin nga problemi 21 në libër. Herb Sutter "Më e jashtëzakonshme C++" (Addison-Wesley, 2002). Rregulli 29 u frymëzua nga eksplorimi i gjerë i Herb Sutter për këtë temë në problemat 8-19 të Exceptional C++, si dhe problemet 17-23 të C++ Më të jashtëzakonshme dhe problemet 11-13 të librit të tij Exceptional C++. Style" (Addison-Wesley, 2005). David Abrahams më ndihmoi të kuptoj më mirë tre parimet e garantimit të sigurisë së përjashtimeve. Idioma e ndërfaqes jo virtuale (NVI) në pikën 35 është marrë nga kolona "Virtualiteti" e Herb Sutter në numrin shtator 2001 të C/C++ Users Journal. Modelet e dizajnit "Template Method" dhe "Strategy" të përmendura në të njëjtin rregull janë marrë nga libri "Design Patterns" (Addison-Wesley, 1995) nga Erich Gamma, Richard Helm, Ralph Johnson (Ralf Johnson) dhe John Vlissides (John Vlissides). Ideja e përdorimit të idiomës NVI në rregullin 37 u sugjerua nga Hendrik Schober. Kontributi i David Smallberg është zbatimi i grupit të përshkruar në pikën 38. Vëzhgimi i bërë në pikën 39 se optimizimi i një klase bazë boshe është thelbësisht i pamundur me trashëgimi të shumëfishtë është marrë nga libri i David Vandevoorde dhe Nicholas M. Jossuthis (Nickolai M. Josuttis) "Templates C++" (Addison-Wesley, 2003). Në artikullin 42, ideja ime fillestare se për çfarë është fjala kyçe e emrit të tipit bazohet në C++ dhe C FAQ ( http://www.comeaucomputing.com/techtalk/#typename) e mbajtur nga Greg Comeau dhe Leor Zolman më ndihmoi të kuptoj se kjo pikëpamje është e gabuar (faji im, jo ​​i Gregut). Tema e rregullit 46 erdhi nga fjalimi i Dan Saks "Si të bësh miq të rinj". Ideja në fund të rregullit 52, që nëse deklaroni një version të ri, duhet të deklaroni të gjithë të tjerët, është paraqitur në problemin 22 të Exceptional C++ të Herb Sutter. Kuptimi im për procesin e rishikimit të Boost (përmbledhur në pikën 55) është sqaruar nga David Abrahams.

    Të gjitha sa më sipër kanë të bëjnë se ku dhe nga kush kam mësuar diçka, pavarësisht se kush e ka publikuar i pari materialin për temën përkatëse.

    Shënimet e mia gjithashtu thonë se kam përdorur informacione nga Steve Clamage, Antoine Trux, Timothy Knox dhe Mike Kaebling, megjithëse për fat të keq nuk specifikohet se ku dhe si.

    Draftet e edicionit të parë të shqyrtuara nga Tom Cargill, Glenn Carroll, Tony Davis, Brian Kernigan, Jak Kirman, Doug Lea, Moises Lejter), Eugene Santos Jr. (Eugene Santos, Jr), John Shewchuk, John Stasko, Bjarne Stroustrup, Barbara Tilly dhe Nancy L. Urbano. Përveç kësaj, kërkesa për përmirësime që u përfshinë në botimet e mëvonshme u bënë nga Nancy L. Urbano, Chris Treichel, David Corbin, Paul Gibson, Steve Vinoski, Tom Tom Cargill, Neil Rhodes, David Bern, Russ Williams, Robert Brazile, Doug Morgan , Uwe Steinmuller, Mark Somer Mark Somer, Doug Moore, David Smallberg, Seith Meltzer, Oleg Steinbuk, David Papurt, Tony Hansen, Peter McCluskey ), Stefan Kuhlins, David Braunegg, Paul Chisholm, Adam Zell, Clovis Tondo, Mike Koelbling, Natraj Kini, Lars Numan, Greg Lutz, Tim Johnson, John Lakos, Roger Scott, Scott Frohman, Alan R ooks), Robert Poor, Eric Nagler, Anton Trax, Cade Roux, Chandrika Gokul, Randy Mangoba dhe Glenn Teitelbaum.

    Draftet e edicionit të dytë të shqyrtuara nga: Derek Bosch, Tim Johnson, Brian Kernighan, Junichi Kimura, Scott Lewandowski, Laura Michaels, David Smallberg, Clovis Tonado, Chris Van Wyk dhe Oleg Zabluda. Botimet e mëvonshme përfituan nga komentet e Daniel Steinberg, Arunprasad Marathe, Doug Stapp, Robert Hall, Cheryl Ferguson, Gary Bartlett, Michael Tamm (Michael Tamm), Kendall Beaman, Eric Nagler, Max Hailperin, Joe Gottman, Richard Weeks, Valentin Bonnard, Jun Hee, Tim King, Don Mailer, Ted Hill, Marc Harrison, Michael Rubinstein, Marc Rodgers, David Goh, Brenton Cooper, Andy Thomas-Cramer, Anton Thrax, John Walt, Brian Sharon, Liam Fitzpatric, Bernd Mohr, Harry Yee (Gary Yee), John O "Hanley (John O" Hanley), Brady Patreson (Brady Paterson), Christopher Peterson (Krishti opher Peterson), Feliks Kluzniak, Isi Dunetz, Christopher Creutzi, Ian Cooper, Carl Harris, Marc Stickel, Clay Budin ), Panayotis Matsinopulos, David Smallberg, Herb Sutter, Pajo Misljencevic, Giulio Agostini, Fredrik Blonqvistnyder, Jim Witold Kuzminski, Kazunobu Kuriyama, Michael Christensen, Jorge Yanez Teruel, Mark Davis, Marty Rabinowitz, Ares Lagae dhe Alexander Medvedev.

    Draftet e hershme të pjesshme të këtij botimi u shqyrtuan nga: Brian Kernighan, Angelique Langer, Jesse Luchley, Roger P. Pedersen, Chris Van Wyck, Nicholas Stroustrup dhe Hendrik Schober. Shqyrtimi i plotë i draftit u shqyrtua nga: Leor Zolman, Mike Tsao, Eric Nagler, Gene Gutnick, David Abrahams, Gerhard Kreuser, Drosos Kouronis, Brian Kernighan, Andrew Krims, Balogh Pal, Emily Jagdhar, Evgeny Kalenkovic, Mike Rose, Enrico Burkera , Jack Reeves, Steve Schirippa, Martin Fallenstedt, Timothy Knox, Yun Bai, Michael Lanzetta, Philip Janert, Judo Bartolucci, Michael Topic, Jeff Sherpeltz, Chris Nauroth, Nishant Mittal, Jeff Sommers, Hal Moroff, Vincent Chang Manis, Brendogn Lee, Jim Meehan, Alan Geller, Siddhartha Singh, Sam Lee, Sasan Dashtinejad, Alex Martin, Steve Kai, Thomas Fruchterman, Corey Hicks, David Smallberg, Gunawardan Kakulapati, Danny Rabbani, Jake Cohen, Hendrik Schuber, Paco Viziana, Glenny D. Oldham, Nicholas Stroustrup, Matthew Wilson, Andrei Alexandrescu, Tim Johnson, Leon Matthews, Peter Dulimov dhe Kevlin Henney. Draftet e disa paragrafëve individualë u shqyrtuan gjithashtu nga Herb Sutter dhe Attila F. Feher.

    Rishikimi i një dorëshkrimi të papërpunuar (dhe ndoshta jo të plotë) është punë e vështirë dhe afatet e ngushta vetëm e bëjnë më të vështirë. I jam mirënjohës të gjithëve që shprehën dëshirën për të më ndihmuar për këtë.

    Rishikimi i një dorëshkrimi është edhe më i vështirë nëse nuk keni ide për materialin, por nuk duhet ta humbisni asnje pasaktësi që mund të depërtojnë në tekst. Është e mahnitshme që ka njerëz që pranojnë të redaktojnë tekstet. Christa Meadowbrook ishte redaktore e këtij libri dhe ishte në gjendje të dallonte mjaft gabime që të gjithë të tjerët i humbën.

    Leor Zolman rishikoi dorëshkrimin për të gjitha mostrat e kodit në përpilues të ndryshëm dhe më pas e bëri përsëri pasi bëra ndryshime. Nëse mbeten ndonjë gabim, unë jam përgjegjës për to, jo Lheor.

    Carl Vigers dhe veçanërisht Tim Johnson shkruan një tekst të shkurtër por të dobishëm për kopertinën.

    John Waite, redaktor i dy botimeve të para të këtij libri, pa maturi pranoi të punonte përsëri në atë cilësi. Asistentja e tij, Denise Michelsen, i përgjigjej pa ndryshim me një buzëqeshje të këndshme vërejtjeve të mia të shpeshta dhe të bezdisshme (të paktën kështu mendoj, megjithëse nuk e kam takuar kurrë personalisht). Julia Nakhil "tërhoqi kashtën e shkurtër", ajo duhej të ishte përgjegjëse për prodhimin e këtij libri. Për gjashtë javë, ajo u ul natën për të mbajtur orarin e saj pa e humbur qetësinë. John Fuller (shefi i saj) dhe Marty Rabinowitz (shefi i tij) ishin gjithashtu të përfshirë drejtpërdrejt në procesin e prodhimit. Detyrat zyrtare të Vanessa Moore ishin të kornizonte librin në FrameMaker dhe të krijonte tekstin PDF, por ajo kontribuoi vullnetarisht në Shtojcën B dhe e formatoi për printim në kopertinën e brendshme. Solveig Huegland ndihmoi me indeksin. Sandra Schroeder dhe Chuti Prasercit ishin përgjegjëse për dizajnin e kopertinës. Ishte Chuti që duhej të ribënte kopertinën sa herë që thosha: “Po ta vendosim këtë foto, por me një shirit të një ngjyre tjetër?”. Chanda Leri-Couty është plotësisht i rraskapitur nga marketingu i librit.

    Gjatë muajve që punova për dorëshkrimin, seriali televiziv Buffy the Vampire Slayer më ndihmoi të largoja stresin në fund të ditës. U desh shumë përpjekje për të përjashtuar fjalimin e Buffy-t nga faqet e këtij libri.

    Kathy Reed më mësoi se si të programoja në vitin 1971 dhe jam e lumtur që mbesim miq edhe sot e kësaj dite. Donald French punësoi mua dhe Moses Legter për të zhvilluar mësime C++ në 1989 (gjë që më bëri vërtetë mësojnë C++), dhe në vitin 1991 më ftoi t'i prezantoj në kompjuterin Stratus. Pastaj studentët më inkurajuan të shkruaj atë që më vonë u bë botimi i parë i këtij libri. Don gjithashtu më prezantoi me John White, i cili pranoi ta botonte.

    Gruaja ime, Nancy L. Urbano, vazhdon të inkurajojë shkrimin tim, edhe pas shtatë librave të botuar, përshtatjeve të CD-ve dhe një disertacioni. Ajo ka një durim të jashtëzakonshëm. Pa të, nuk do të kisha mundur kurrë të bëja atë që bëra.

    Nga fillimi deri në fund, qeni ynë Persefona ka qenë shoqëruesja ime altruiste. Fatkeqësisht, ajo mori pjesë në pjesën më të madhe të projektit ndërsa ishte tashmë në urnën e varrimit. Na mungon shumë ajo.

    Artikujt kryesorë të lidhur