Kako podesiti pametne telefone i računare. Informativni portal

Efikasna upotreba na 55 sigurnih načina.

Ime: Najbolje upotrebe za C ++ - 35 novih najboljih praksi za poboljšanje vaših programa i projekata.

U knjizi, koja je nastavak popularnog izdanja Efektivnog C ++, možete naučiti kako najefikasnije koristiti konstrukcije jezika C ++, kao i razmotriti metode lijevanja, implementaciju RTTI mehanizma, operator pravila preopterećenja, itd. Knjiga daje preporuke za upotrebu pametnih pokazivača, virtuelnih konstruktora, baferovanog new operatora, proxy klasa i dvostrukog dispečera. Posebna pažnja posvećena je radu sa izuzecima i mogućnostima upotrebe C koda u programima napisanim na C++. Najnovije karakteristike jezika su detaljno prikazane i predstavljene kako uz njihovu pomoć povećati performanse programa. Aplikacije pohranjuju kod šablona auto_ptr i označenu listu C++ referenci i Internet resursa.


Sadržaj
Uvod. četrnaest
Poglavlje 1. Osnove. 23
Pravilo 1. Razlikujte pokazivače i veze. 23
Pravilo 2. Preferirajte prebacivanja u C ++ stilu. 25
Pravilo 3. Nikada nemojte koristiti polimorfizam na nizovima. trideset
Pravilo 4. Izbjegavajte nepotrebne zadane konstruktore. 33
Poglavlje 2. Operateri. 38
Pravilo 5. Čuvajte se UDF-ova. 38
Pravilo 6. Pravite razliku između prefiksnih i postfiksnih oblika operatora povećanja i dekrementa. 45
Pravilo 7. Nikada nemojte preopteretiti &&, 11 i operatore. 48
Pravilo 8. Razlikujte značenje operatora new i delete. 51
Poglavlje 3. Izuzeci. 57
Pravilo 9. Da biste izbjegli curenje resursa, koristite destruktore. 58
Pravilo 10. Izbjegavajte curenje resursa u konstruktorima. 63
Pravilo 11. Nemojte širiti rukovanje izuzetkom izvan destruktora. 71
Pravilo 12. Razlikujte bacanje izuzetka od prosljeđivanja parametra ili pozivanja virtualne funkcije. 73
Pravilo 13. Hvatanje izuzetaka po referenci. 80
Pravilo 14. Koristite specifikacije izuzetaka mudro. 84
Pravilo 15. Procijenite troškove rukovanja izuzecima. 90
Poglavlje 4. Efikasnost. 94
Pravilo 16. Ne zaboravite pravilo 80-20. 95
Pravilo 17. Koristite lijeno računanje. 97
Pravilo 18. Smanjite troškove očekivanih proračuna. 106
Pravilo 19. Istražite uzroke privremenih objekata. 110
Pravilo 20. Olakšajte optimizaciju povratne vrijednosti. 113
Pravilo 21. Koristite preopterećenje da biste izbjegli implicitnu konverziju tipa. 116
Pravilo 22: Kad god je moguće, koristite operator dodjeljivanja umjesto zasebnog operatora. 118
Pravilo 23. Koristite različite biblioteke. 121
Pravilo 24: Uzmite u obzir troškove povezane s virtualnim funkcijama, višestrukim nasljeđivanjem, virtualnim baznim klasama i RTTI. 124
Poglavlje 5. Prijemi. 134
Pravilo 25. Napravite virtualne konstruktore i funkcije koje nisu članovi klase. 134
Pravilo 26. Ograničite broj objekata u klasi. 140
Pravilo 27: Zahtijevajte ili odbijte dodjelu hrpe prema potrebi. 154
Pravilo 28. Koristite pametne pokazivače. 167
Pravilo 29. Koristite brojanje referenci. 190
Pravilo 30. Koristite proxy klase. 218
Pravilo 31. Kreirajte funkcije koje su virtualne u odnosu na više od jednog objekta. 231
Poglavlje 6. Razno. 254
Pravilo 32. Program za budućnost. 254
Pravilo 33. Učinite neterminalne klase apstraktnim. 259
Pravilo 34. Znati koristiti vodeni C i C++ program. 270
Pravilo 35. Upoznajte se sa jezičkim standardom. 276
Dodatak 1. Spisak preporučene literature. 284
Dodatak 2. Implementacija predloška auto_ptr.

Operateri.
Prema preopterećenim operaterima treba se odnositi s poštovanjem. Oni vam omogućavaju da primijenite istu sintaksu na korisnički definirane tipove kao i na ugrađene tipove, a također pružaju nečuvene perspektive zahvaljujući funkcijama koje stoje iza ovih operatora. Ali mogućnost da karakteri poput + ili - rade šta god želite takođe znači da preopterećeni operatori mogu učiniti programe potpuno nerazumljivim. Međutim, postoji mnogo vještih C++ programera koji znaju kako iskoristiti moć preopterećenih operatera bez pretvaranja programa u crnu kutiju.

Nažalost, manje vještim je lako napraviti greške. Konstruktori sa samo jednim argumentom i implicitnim operatorima konverzije tipa mogu biti posebno problematični jer se njihovi pozivi ne podudaraju uvijek u izvorni tekstovi programe. To dovodi do pojave programa čije je ponašanje vrlo teško razumjeti. Drugi problem se javlja kada se preopterećuju operatori kao što su && i II, jer prelazak sa ugrađenih operatora na funkcije koje su napisali korisnici rezultira suptilnim promenama u semantici koje je lako prevideti. Konačno, mnogi operatori se međusobno povezuju prema standardnim pravilima, a zbog preopterećenosti operatora ponekad se krše opšteprihvaćeni odnosi.

U pravilima koja slijede, pokušao sam objasniti kada i kako se koriste preopterećeni operatori, kako se ponašaju, kako bi trebali biti međusobno povezani i kako se svi mogu kontrolisati. Kada savladate materijale iz ovog poglavlja, preopteretiti ćete (ili ne preopteretiti) operatere sa istim samopouzdanjem kao pravi profesionalac.

Besplatno preuzimanje e-knjiga u prikladnom formatu, gledajte i čitajte:
Preuzmite knjigu Iskoristite C++ na najbolji način - 35 novih savjeta za poboljšanje vaših programa i projekata - Meyers S. - fileskachat.com, brzo i besplatno.

Preuzmite djvu
U nastavku možete kupiti ovu knjigu po najboljoj sniženoj cijeni uz dostavu širom Rusije.

Scott Meyers

Efikasna upotreba C++. 55 sigurnih načina za poboljšanje strukture i koda vaših programa

Recenzije trećeg izdanjaEfikasna upotreba C ++

Knjiga Scotta Meyersa Efikasno korištenje C ++, treće izdanje- je koncentracija programskog iskustva - iskustvo koje bi vam bez njega skupo donijelo. Ova knjiga je odličan izvor koji preporučujem svima koji profesionalno pišu C++.

Peter Dulimov, ME, inženjer, Jedinica za evaluaciju i istraživanje, NAVSYSCOM, Australija

Treće izdanje ostaje najbolja knjiga o tome kako spojiti sve delove C ++ da bi se kreirali efikasni i konzistentni programi. Ako se prijavljujete za C++ programera, trebali biste to pročitati.

Eric Nagler, konsultant, trener i autor Learning C++

Prvo izdanje ove knjige bilo je jedno od malog (vrlo malog) broja knjiga koje su mi pomogle da značajno poboljšam svoj nivo profesionalnog programera softvera. Kao i druge knjige iz ove serije, pokazala se kao praktična i laka za čitanje, ali je sadržavala i mnogo važnih savjeta. „Efektivno korišćenje C ++ ", treće izdanje, nastavlja ovu tradiciju. C++ je veoma moćan jezik programiranje. Ako C pruža konopac za penjanje na vrh planine, onda je C++ cijela prodavnica u kojoj su razni ljudi spremni da vam pomognu da vežete čvorove na ovom užetu. Savladavanje gradiva iz ove knjige definitivno će povećati vašu sposobnost da efikasno koristite C++ bez umiranja od stresa.

Jack W. Reeves, Izvršni direktor Bleading Edge Software Technologies

Svaki novi programer ko dođe u moj tim, odmah dobije zadatak - da pročita ovu knjigu.

Michael Lancetta, vodeći softverski inženjer

Pročitao sam prvo izdanje Efikasno korištenje C++ prije otprilike 9 godina i ova knjiga je odmah postala jedna od mojih omiljenih C++ knjiga. Po mom mišljenju, treće izdanje knjige Efikasno korišćenje C++ ostaje obavezno čitanje za svakoga ko želi efikasno programirati na C++. Živjet ćemo u boljem svijetu ako C++ programeri pročitaju ovu knjigu prije nego što napišu prvi red profesionalnog koda.

Danny Rabbani, softverski inženjer

Prvo izdanje Skota Mejersa Efektivno korišćenje C ++ stiglo mi je kada sam bio prosečan programer i trudio sam se da uradim najbolje što sam mogao. I to je bio spas! Otkrio sam da je Meyersov savjet praktično koristan i djelotvoran, da će 100% ispuniti ono što obećava. Treće izdanje pomaže u praktičnoj upotrebi C ++ pri radu na modernim ozbiljnim softverskim projektima, pružajući informacije o najnovijim karakteristikama i mogućnostima jezika. Sa zadovoljstvom sam otkrio da u trećem izdanju knjige mogu pronaći mnogo novih i zanimljivih stvari za sebe, koje, kako mi se činilo, jako dobro poznajem.

Michael Topek, tehnički menadžer programa

Ovaj autoritativni vodič Scott Meyersa, C++ gurua, namijenjen je svima koji žele koristiti C++ bezbedno i efikasno, ili koji prelaze na C++ sa bilo kog drugog objektno orijentisanog jezika. Ova knjiga sadrži vrijedne informacije predstavljene jasnim, sažetim, zabavnim i pronicljivim stilom.

Siddhartha Karan Singh, programer softvera

Priznanja

Knjiga "Upotreba C ++ Efektivno" postoji već 15 godina, a ja sam počeo da učim C ++ oko 5 godina pre nego što sam je napisao. Dakle, rad na ovom projektu traje već oko 20 godina. Za to vrijeme dobio sam želje, komentare, ispravke, a ponekad i ogromna zapažanja od stotina (hiljada?) ljudi. Svaki od njih doprinio je razvoju "Efektivnog korištenja C ++". Svima sam im zahvalan.

Odavno sam odustao od pokušaja da se sjetim gdje i šta sam sam naučio, ali ne mogu a da ne spomenem jedan izvor, jer ga stalno koristim. To su Usenet diskusione grupe, posebno comp.lang.c ++.Moderated i comp.std.c++. Mnoga pravila u ovoj knjizi (možda većina) rezultat su razmišljanja o tehničkim idejama o kojima se raspravlja u ovim grupama.

Steve Dewhurst mi je pomogao u odabiru novog materijala za treće izdanje knjige. Pravilo 11 preuzima ideju kopiranja i zamjene implementacije operatora = iz bilješki Herba Suttera, Problem 13 iz njegove knjige Exceptional C++ (Addison-Wesley, 2000). Ideja o preuzimanju resursa kao inicijalizacije (pravilo 13) dolazi iz Programskog jezika C++ (Addison-Wesley, 2002) Bjarnea Stroustrupa. Ideja koja stoji iza Pravila 17 preuzeta je iz odjeljka "Najbolje prakse" na Boost shared_ptr web-mjestu (http://boost.org/libs/ smart_ptr / shared_ptr.htm # BestPractices) i prerađena na osnovu materijala u problemu 21 u knjizi Herb Sutter, "Izuzetniji C++" (Addison-Wesley, 2002). Pravilo 29 inspirisano je opsežnim istraživanjem ove teme Herba Suttera u Izuzetnim C++ problemima 8-19, Izuzetnijim C++ problemima 17-23 i Iznimnim C++ problemima 11-13. Stil ”(Addison-Wesley, 2005) . David Abrahams mi je pomogao da bolje razumijem tri principa osiguravanja sigurnosti izuzetaka. Idiom nevirtuelnog interfejsa (NVI) u Pravilu 35 preuzet je iz Sutterove kolone "Virtualnost" u C / C ++ Users Journalu iz septembra 2001. godine. Metoda šablona i obrasci dizajna strategije koji se spominju u istom pravilu preuzeti su iz Design Patterns (Addison-Wesley, 1995) Ericha Gamme, Richarda Helma, Ralpha Johnsona (Ralf Johnson i John Vlissides). Ideja za idiom NVI u pravilu 37 potekla je od Hendrika Schobera. Doprinos Davida Smallberga implementaciji skupa opisanoj u točki 38. Opažanje u točki 39 da je optimizacija prazne bazne klase u osnovi nemoguća s višestrukim nasljeđivanjem je od Davida Vandevoordea i Nikolaja M. Josutisa (Nickolai M. Josuttis) "Šabloni C ++ (Addison-Wesley, 2003). Moja početna ideja o tome šta je ključna riječ typename u pravilu 42 zasniva se na C++ i C FAQ (http://www.comeaucomputing.com/techtalk/ #typename), koji podržavaju Greg Comeau i Leor Zolman mi je pomogao da shvatim da je ovo gledište pogrešno (moja greška, ne Gregova). Tema za pravilo 46 potiče iz govora Dana Saksa "Kako steći nove prijatelje". Ideja na kraju Pravila 52 da, ako deklarirate jednu verziju nove, morate deklarirati sve ostale, iznesena je u problemu 22 Izuzetnog C++ Herba Suttera. Moje razumijevanje procesa provjere Boost (sažeto u pravilu 55) je poboljšao David Abrahams.

Scott Meyers

Efikasna upotreba C++. 55 sigurnih načina za poboljšanje strukture i koda vaših programa

Recenzije trećeg izdanjaEfikasna upotreba C++

Knjiga Scotta Meyersa Efikasno korištenje C ++, treće izdanje- je koncentracija programskog iskustva - iskustvo koje bi vam bez njega skupo donijelo. Ova knjiga je odličan izvor koji preporučujem svima koji profesionalno pišu C++.

Peter Dulimov, ME, inženjer, Jedinica za evaluaciju i istraživanje, NAVSYSCOM, Australija

Treće izdanje ostaje najbolja knjiga o tome kako spojiti sve delove C ++ da bi se kreirali efikasni i konzistentni programi. Ako se prijavljujete za C++ programera, trebali biste to pročitati.

Eric Nagler, konsultant, trener i autor Learning C++

Prvo izdanje ove knjige bilo je jedno od malog (vrlo malog) broja knjiga koje su mi pomogle da značajno poboljšam svoj nivo profesionalnog programera softvera. Kao i druge knjige iz ove serije, pokazala se kao praktična i laka za čitanje, ali je sadržavala i mnogo važnih savjeta. „Efektivno korišćenje C ++ ", treće izdanje, nastavlja ovu tradiciju. C++ je veoma moćan programski jezik. Ako C pruža konopac za penjanje na vrh planine, onda je C ++ čitava prodavnica u kojoj su razni ljudi spremni da vam pomognu da vežete čvorove na ovom užetu. Savladavanje gradiva iz ove knjige definitivno će povećati vašu sposobnost da efikasno koristite C++ bez umiranja od stresa.

Jack W. Reeves, izvršni direktor, Bleading Edge Software Technologies

Svaki novi programer koji se pridruži mom timu odmah dobija zadatak da pročita ovu knjigu.

Michael Lancetta, vodeći softverski inženjer

Pročitao sam prvo izdanje Efikasno korištenje C++ prije otprilike 9 godina i ova knjiga je odmah postala jedna od mojih omiljenih C++ knjiga. Po mom mišljenju, treće izdanje knjige Efikasno korišćenje C++ ostaje obavezno čitanje za svakoga ko želi efikasno programirati na C++. Živjet ćemo u boljem svijetu ako C++ programeri pročitaju ovu knjigu prije nego što napišu prvi red profesionalnog koda.

Danny Rabbani, softverski inženjer

Prvo izdanje Skota Mejersa Efektivno korišćenje C ++ stiglo mi je kada sam bio prosečan programer i trudio sam se da uradim najbolje što sam mogao. I to je bio spas! Otkrio sam da je Meyersov savjet praktično koristan i djelotvoran, da će 100% ispuniti ono što obećava. Treće izdanje pomaže u praktičnoj upotrebi C ++ pri radu na modernim ozbiljnim softverskim projektima, pružajući informacije o najnovijim karakteristikama i mogućnostima jezika. Sa zadovoljstvom sam otkrio da u trećem izdanju knjige mogu pronaći mnogo novih i zanimljivih stvari za sebe, koje, kako mi se činilo, jako dobro poznajem.

Michael Topek, tehnički menadžer programa

Ovaj autoritativni vodič Scott Meyersa, C++ gurua, namijenjen je svima koji žele koristiti C++ bezbedno i efikasno, ili koji prelaze na C++ sa bilo kog drugog objektno orijentisanog jezika. Ova knjiga sadrži vrijedne informacije predstavljene jasnim, sažetim, zabavnim i pronicljivim stilom.

Siddhartha Karan Singh, programer softvera

Priznanja

Knjiga "Upotreba C ++ Efektivno" postoji već 15 godina, a ja sam počeo da učim C ++ oko 5 godina pre nego što sam je napisao. Dakle, rad na ovom projektu traje već oko 20 godina. Za to vrijeme dobio sam želje, komentare, ispravke, a ponekad i ogromna zapažanja od stotina (hiljada?) ljudi. Svaki od njih doprinio je razvoju "Efektivnog korištenja C ++". Svima sam im zahvalan.

Odavno sam odustao od pokušaja da se sjetim gdje i šta sam sam naučio, ali ne mogu a da ne spomenem jedan izvor, jer ga stalno koristim. To su Usenet diskusione grupe, posebno comp.lang.c ++.Moderated i comp.std.c++. Mnoga pravila u ovoj knjizi (možda većina) rezultat su razmišljanja o tehničkim idejama o kojima se raspravlja u ovim grupama.

Steve Dewhurst mi je pomogao u odabiru novog materijala za treće izdanje knjige. Pravilo 11 preuzima ideju kopiranja i zamjene implementacije operatora = iz bilješki Herba Suttera, Problem 13 iz njegove knjige Exceptional C++ (Addison-Wesley, 2000). Ideja o preuzimanju resursa kao inicijalizacije (pravilo 13) dolazi iz Programskog jezika C++ (Addison-Wesley, 2002) Bjarnea Stroustrupa. Ideja koja stoji iza Pravila 17 preuzeta je iz odjeljka "Najbolje prakse" na Boost shared_ptr web-mjestu (http://boost.org/libs/ smart_ptr / shared_ptr.htm # BestPractices) i prerađena na osnovu materijala u problemu 21 u knjizi Herb Sutter, "Izuzetniji C++" (Addison-Wesley, 2002). Pravilo 29 inspirisano je opsežnim istraživanjem ove teme Herba Suttera u Izuzetnim C++ problemima 8-19, Izuzetnijim C++ problemima 17-23 i Iznimnim C++ problemima 11-13. Stil ”(Addison-Wesley, 2005) . David Abrahams mi je pomogao da bolje razumijem tri principa osiguravanja sigurnosti izuzetaka. Idiom nevirtuelnog interfejsa (NVI) u Pravilu 35 preuzet je iz Sutterove kolone "Virtualnost" u C / C ++ Users Journalu iz septembra 2001. godine. Metoda šablona i obrasci dizajna strategije koji se spominju u istom pravilu preuzeti su iz Design Patterns (Addison-Wesley, 1995) Ericha Gamme, Richarda Helma, Ralpha Johnsona (Ralf Johnson i John Vlissides). Ideja za idiom NVI u pravilu 37 potekla je od Hendrika Schobera. Doprinos Davida Smallberga implementaciji skupa opisanoj u točki 38. Opažanje u točki 39 da je optimizacija prazne bazne klase u osnovi nemoguća s višestrukim nasljeđivanjem je od Davida Vandevoordea i Nikolaja M. Josutisa (Nickolai M. Josuttis) "Šabloni C ++ (Addison-Wesley, 2003). Moja početna ideja o tome šta je ključna riječ typename u pravilu 42 zasniva se na C++ i C FAQ (http://www.comeaucomputing.com/techtalk/ #typename), koji podržavaju Greg Comeau i Leor Zolman mi je pomogao da shvatim da je ovo gledište pogrešno (moja greška, ne Gregova). Tema za pravilo 46 potiče iz govora Dana Saksa "Kako steći nove prijatelje". Ideja na kraju Pravila 52 da, ako deklarirate jednu verziju nove, morate deklarirati sve ostale, iznesena je u problemu 22 Izuzetnog C++ Herba Suttera. Moje razumijevanje procesa provjere Boost (sažeto u pravilu 55) je poboljšao David Abrahams.

Sve navedeno se tiče gdje i od koga sam nešto naučio, bez obzira ko je prvi objavio materijal na relevantnu temu.

U mojim bilješkama također stoji da sam koristio informacije od Stevea Clamagea, Antoinea Truxa, Timothyja Knoxa i Mikea Kaelblinga, iako nažalost nije precizirano gdje i kako.

Nacrte prvog izdanja recenzirali Tom Cargill, Glenn Caroll, Tony Davis, Brian Kernigan, Jak Kirman, Doug Lea, Moises Lejter), Eugene Santos Jr. (Eugene Santos, Jr.), John Shewchuk, John Stasko, Bjarne Stroustrup, Barbara Tilly i Nancy L. Urbano. Osim toga, prijedloge za poboljšanja koja su ugrađena u kasnija reizdanja dali su 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 Trucks, Cade Roux, Chandrika Gokul, Randy Mangoba i Glenn Teitelbaum.

Nacrte drugog izdanja recenzirali: Derek Bosch, Tim Johnson, Brian Kernighan, Junichi Kimura, Scott Lewandowski, Laura Michaels, David Smallberg, Clovis Tonado, Chris Van Wyk i Oleg Zabluda. U kasnijim serijama koristili su komentari Daniela Steinberga, Arunprasada Maratha, Douga Stappa, Roberta Halla, Cheryl Ferguson, Gary Bartlett, Michaela Bartla Tam Michael Tamma, Kendall Beaman, Erica Naglera, Maxa Hailperina, Joea Gottmana, Richarda Weeksa, Valentina Bonnarda, Juna On, Tim King, Don Mailer, Ted Hill, Marc Harrison, Michael Rubinstein, Marc Rodgers, David Goh, Brenton Brenton Cooper, Andy Thomas-Cramer, Anton Trucks, John Walt, Brian Sharon, Liam Fitzpatric, Bernd Mohr, Harry Yee ( Gary Yee), John O "Henley, Brady Paterson, Christopher Peterson (Hrist opher Peterson, Feliks Kluzniak, Isi Dunetz, Christopher Creutzi, Ian Cooper, Carl Harris, Marc Stickel, Clay Budin, Panayotis Matsinopulos, David Smallberg, Herb Sutter, Pajo Mišljenčević, Giulio Agostini, Fredrik Blomqvistrik (Fred Wilnderqvistrense), J. Kuzminski, Kazunobu Kuriyama, Michael Christensen, Jorge Yanez Teruel, Mark Davis, Marty Rabinowitz, Ares Lagae (Ares Lagae) i Alexander Medvedev.

Scott Meyers

Efikasna upotreba C++. 55 sigurnih načina za poboljšanje strukture i koda vaših programa

Recenzije trećeg izdanja

Efikasna upotreba C++

Knjiga Scotta Meyersa Efikasno korištenje C ++, treće izdanje- je koncentracija programskog iskustva - iskustvo koje bi vam bez njega skupo donijelo. Ova knjiga je odličan izvor koji preporučujem svima koji profesionalno pišu C++.

Peter Dulimov, ME, inženjer, Jedinica za evaluaciju i istraživanje, NAVSYSCOM, Australija

Treće izdanje ostaje najbolja knjiga o tome kako spojiti sve delove C ++ da bi se kreirali efikasni i konzistentni programi. Ako se prijavljujete za C++ programera, trebali biste to pročitati.

Eric Nagler, konsultant, trener i autor Learning C++

Prvo izdanje ove knjige bilo je jedno od malog (vrlo malog) broja knjiga koje su mi pomogle da značajno poboljšam svoj nivo profesionalnog programera softvera. Kao i druge knjige iz ove serije, pokazala se kao praktična i laka za čitanje, ali je sadržavala i mnogo važnih savjeta. „Efektivno korišćenje C ++ ", treće izdanje, nastavlja ovu tradiciju. C++ je veoma moćan programski jezik. Ako C pruža konopac za penjanje na vrh planine, onda je C ++ čitava prodavnica u kojoj su razni ljudi spremni da vam pomognu da vežete čvorove na ovom užetu. Savladavanje gradiva iz ove knjige definitivno će povećati vašu sposobnost da efikasno koristite C++ bez umiranja od stresa.

Jack W. Reeves, izvršni direktor, Bleading Edge Software Technologies

Svaki novi programer koji se pridruži mom timu odmah dobija zadatak da pročita ovu knjigu.

Michael Lancetta, vodeći softverski inženjer

Pročitao sam prvo izdanje Efikasno korištenje C++ prije otprilike 9 godina i ova knjiga je odmah postala jedna od mojih omiljenih C++ knjiga. Po mom mišljenju, treće izdanje knjige Efikasno korišćenje C++ ostaje obavezno čitanje za svakoga ko želi efikasno programirati na C++. Živjet ćemo u boljem svijetu ako C++ programeri pročitaju ovu knjigu prije nego što napišu prvi red profesionalnog koda.

Danny Rabbani, softverski inženjer

Prvo izdanje Skota Mejersa Efektivno korišćenje C ++ stiglo mi je kada sam bio prosečan programer i trudio sam se da uradim najbolje što sam mogao. I to je bio spas! Otkrio sam da je Meyersov savjet praktično koristan i djelotvoran, da će 100% ispuniti ono što obećava. Treće izdanje pomaže u praktičnoj upotrebi C ++ pri radu na modernim ozbiljnim softverskim projektima, pružajući informacije o najnovijim karakteristikama i mogućnostima jezika. Sa zadovoljstvom sam otkrio da u trećem izdanju knjige mogu pronaći mnogo novih i zanimljivih stvari za sebe, koje, kako mi se činilo, jako dobro poznajem.

Michael Topek, tehnički menadžer programa

Ovaj autoritativni vodič Scott Meyersa, C++ gurua, namijenjen je svima koji žele koristiti C++ bezbedno i efikasno, ili koji prelaze na C++ sa bilo kog drugog objektno orijentisanog jezika. Ova knjiga sadrži vrijedne informacije predstavljene jasnim, sažetim, zabavnim i pronicljivim stilom.

Siddhartha Karan Singh, programer softvera

Priznanja

Knjiga "Upotreba C ++ Efektivno" postoji već 15 godina, a ja sam počeo da učim C ++ oko 5 godina pre nego što sam je napisao. Dakle, rad na ovom projektu traje već oko 20 godina. Za to vrijeme dobio sam želje, komentare, ispravke, a ponekad i ogromna zapažanja od stotina (hiljada?) ljudi. Svaki od njih doprinio je razvoju "Efektivnog korištenja C ++". Svima sam im zahvalan.

Odavno sam odustao od pokušaja da se sjetim gdje i šta sam sam naučio, ali ne mogu a da ne spomenem jedan izvor, jer ga stalno koristim. To su Usenet diskusione grupe, posebno comp.lang.c ++.Moderated i comp.std.c++. Mnoga pravila u ovoj knjizi (možda većina) rezultat su razmišljanja o tehničkim idejama o kojima se raspravlja u ovim grupama.

Steve Dewhurst mi je pomogao u odabiru novog materijala za treće izdanje knjige. Pravilo 11 preuzima ideju kopiranja i zamjene implementacije operatora = iz bilješki Herba Suttera, Problem 13 iz njegove knjige Exceptional C++ (Addison-Wesley, 2000). Ideja o preuzimanju resursa kao inicijalizacije (pravilo 13) dolazi iz Programskog jezika C++ (Addison-Wesley, 2002) Bjarnea Stroustrupa. Ideja koja stoji iza Pravila 17 preuzeta je iz odjeljka "Najbolje prakse" na Boost shared_ptr web-mjestu (http://boost.org/libs/ smart_ptr / shared_ptr.htm # BestPractices) i prerađena na osnovu materijala u problemu 21 u knjizi Herb Sutter, "Izuzetniji C++" (Addison-Wesley, 2002). Pravilo 29 inspirisano je opsežnim istraživanjem ove teme Herba Suttera u Izuzetnim C++ problemima 8-19, Izuzetnijim C++ problemima 17-23 i Iznimnim C++ problemima 11-13. Stil ”(Addison-Wesley, 2005) . David Abrahams mi je pomogao da bolje razumijem tri principa osiguravanja sigurnosti izuzetaka. Idiom nevirtuelnog interfejsa (NVI) u Pravilu 35 preuzet je iz Sutterove kolone "Virtualnost" u C / C ++ Users Journalu iz septembra 2001. godine. Metoda šablona i obrasci dizajna strategije koji se spominju u istom pravilu preuzeti su iz Design Patterns (Addison-Wesley, 1995) Ericha Gamme, Richarda Helma, Ralpha Johnsona (Ralf Johnson i John Vlissides). Ideja za idiom NVI u pravilu 37 potekla je od Hendrika Schobera. Doprinos Davida Smallberga implementaciji skupa opisanoj u točki 38. Opažanje u točki 39 da je optimizacija prazne bazne klase u osnovi nemoguća s višestrukim nasljeđivanjem je od Davida Vandevoordea i Nikolaja M. Josutisa (Nickolai M. Josuttis) "Šabloni C ++ (Addison-Wesley, 2003). Moja početna ideja o tome šta je ključna riječ typename u pravilu 42 zasniva se na C++ i C FAQ (http://www.comeaucomputing.com/techtalk/ #typename), koji podržavaju Greg Comeau i Leor Zolman mi je pomogao da shvatim da je ovo gledište pogrešno (moja greška, ne Gregova). Tema za pravilo 46 potiče iz govora Dana Saksa "Kako steći nove prijatelje". Ideja na kraju Pravila 52 da, ako deklarirate jednu verziju nove, morate deklarirati sve ostale, iznesena je u problemu 22 Izuzetnog C++ Herba Suttera. Moje razumijevanje procesa provjere Boost (sažeto u pravilu 55) je poboljšao David Abrahams.

Sve navedeno se tiče gdje i od koga sam nešto naučio, bez obzira ko je prvi objavio materijal na relevantnu temu.

U mojim bilješkama također stoji da sam koristio informacije od Stevea Clamagea, Antoinea Truxa, Timothyja Knoxa i Mikea Kaelblinga, iako nažalost nije precizirano gdje i kako.

Nacrte prvog izdanja recenzirali Tom Cargill, Glenn Caroll, Tony Davis, Brian Kernigan, Jak Kirman, Doug Lea, Moises Lejter), Eugene Santos Jr. (Eugene Santos, Jr.), John Shewchuk, John Stasko, Bjarne Stroustrup, Barbara Tilly i Nancy L. Urbano. Osim toga, prijedloge za poboljšanja koja su ugrađena u kasnija reizdanja dali su 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 Trucks, Cade Roux, Chandrika Gokul, Randy Mangoba i Glenn Teitelbaum.

Nacrte drugog izdanja recenzirali: Derek Bosch, Tim Johnson, Brian Kernighan, Junichi Kimura, Scott Lewandowski, Laura Michaels, David Smallberg, Clovis Tonado, Chris Van Wyk i Oleg Zabluda. U kasnijim serijama koristili su komentari Daniela Steinberga, Arunprasada Maratha, Douga Stappa, Roberta Halla, Cheryl Ferguson, Gary Bartlett, Michaela Bartla Tam Michael Tamma, Kendall Beaman, Erica Naglera, Maxa Hailperina, Joea Gottmana, Richarda Weeksa, Valentina Bonnarda, Juna On, Tim King, Don Mailer, Ted Hill, Marc Harrison, Michael Rubinstein, Marc Rodgers, David Goh, Brenton Brenton Cooper, Andy Thomas-Cramer, Anton Trucks, John Walt, Brian Sharon, Liam Fitzpatric, Bernd Mohr, Harry Yee ( Gary Yee), John O "Henley, Brady Paterson, Christopher Peterson (Hrist opher Peterson, Feliks Kluzniak, Isi Dunetz, Christopher Creutzi, Ian Cooper, Carl Harris, Marc Stickel, Clay Budin, Panayotis Matsinopulos, David Smallberg, Herb Sutter, Pajo Mišljenčević, Giulio Agostini, Fredrik Blomqvistrik (Fred Wilnderqvistrense), J. Kuzminski, Kazunobu Kuriyama, Michael Christensen, Jorge Yanez Teruel, Mark Davis, Marty Rabinowitz, Ares Lagae (Ares Lagae) i Alexander Medvedev.

Rane djelomične nacrte ovog izdanja recenzirali su: Brian Kernighan, Angelica Lunger, Jesse Lachley, Roger P. Pedersen, Chris Van Wyck, Nicholas Stroustrup i Hendrick Schober. Kompletan nacrt pregledali su: Leor Zolman, Mike Tsao, Eric Nagler, Zhenet Gutnik, David Abrahams, Gerhard Kreuser, Drosos Kouronis, Brian Kernigan, Andrew Crims, Balog Pal, Emily Jagdhar, Eugene Kalenkovich, Mike Rose, Benjko Carrarara, Jack Reeves, Steve Shirippa, Martin Fallenstedt, Timothy Knox, Yoon Bai, Michael Lancetta, Philip Janert, Judo Bartholucci, Michael Topic, Jeff Scherpeltz, Chris Naurot, Nishant Mittal, Jeff Sommers, Hrendon Morungoff Lee, Jim Meellerth, Al Geehan, Al Sing, Sam Lee, Sasan Dashinejad, Alex Martin, Steve Cai, Thomas Fruchterman, Corey Hicks, David Smallberg, Gunawardan Kakulapati, Danny Rabbani, Jake Cohen, Hendrik Schuber, Paco Wiziana, Glenn Jeffrey D. Oldham, Nicholas Stroustrup, Matthew Andrei Alexandrescu, Tim Johnson, Leon Matthews, Peter Dulimov i Kevlin Henney. Neke pojedinačne paragrafe su također izradili Herb Sutter i Attila F. Feher.

Recenzija sirovog (i možda nekompletnog) rukopisa je težak posao, a kratki rokovi ga samo dodatno otežavaju. Zahvalan sam svima koji su izrazili želju da mi pomognu u tome.

Pregled rukopisa je tim teži ako nemate pojma o materijalu, ali ga ne smijete propustiti nijedan netačnosti koje su se mogle uvući u tekst. Neverovatno je da ima ljudi koji su voljni da uređuju tekstove. Christa Meadowbrook je bila urednica ove knjige i bila je u stanju da identifikuje mnoge greške koje su svi ostali propustili.

Leor Zolman je provjerio sve primjere koda na različitim kompajlerima tokom pregleda rukopisa, a onda je to učinio ponovo nakon što sam napravio izmjene. Ako neka greška ostane, ja sam odgovoran za njih, a ne Leor.

Karl Wigers i posebno Tim Johnson napisali su kratak, ali koristan naslovni tekst.

Džon Vejt, urednik prva dva izdanja ove knjige, nehotice je pristao da ponovo radi u ovom svojstvu. Njegova asistentica, Denise Mikelsen, je uvijek odgovarala ugodnim osmijehom na moje česte i dosadne primjedbe (barem tako mislim, iako je lično nikad nisam sreo). Julia Nahil je "izvukla kratku slamku", morala je biti odgovorna za izradu ove knjige. Šest sedmica je sjedila noću kako bi pratila svoj raspored bez gubljenja prisebnosti. John Fuller (njen šef) i Marty Rabinovich (njen šef) su također bili direktno uključeni u pripremu publikacije. Službene dužnosti Vanesse Moore bile su da postavi knjigu u FrameMaker i kreira PDF tekst, ali se dobrovoljno prijavila da doda Dodatak B i formatira ga za štampanje na unutrašnjoj korici. Solveig Hugland je pomogao sa indeksom. Sandra Schreueder i Chuti Praserzit su bile zadužene za dizajn omota. Čuči je bio taj koji je morao da prepravlja naslovnicu svaki put kada sam rekao: "Kako bi bilo da stavim ovu fotografiju, ali sa prugom druge boje?" Chanda Lehry-Cooty je bila potpuno iscrpljena reklamirajući knjigu.

Nekoliko mjeseci dok sam radio na rukopisu, televizijska serija Buffy ubica vampira pomogla mi je da se oslobodim stresa na kraju dana. Bilo je potrebno mnogo truda da se Buffyin govor izbaci sa stranica ove knjige.

Katie Reed me naučila programiranje 1971. i drago mi je da smo ostali prijatelji do danas. Donald French je unajmio Mosesa Lejtera i mene da razvijemo C++ tutorijale 1989. (što me je natjeralo stvarno naučite C++), a 1991. doveo me da ih predstavim na Stratus računaru. Tada su me studenti ohrabrili da napišem ono što će kasnije postati prvo izdanje ove knjige. Don me je takođe upoznao sa Džonom Vajtom, koji je pristao da ga objavi.

Moja supruga, Nensi L. Urbano, nastavlja da podstiče moje pisanje, čak i nakon sedam objavljenih knjiga, prilagođavajući ih za CD i disertaciju. Ima neverovatno strpljenje. Bez nje nikada ne bih mogao da uradim ono što sam uradio.

Od početka do kraja, naš pas Persefona je bio moj nesebičan pratilac. Nažalost, učestvovala je u većini projekta dok je već bila u grobnoj urni. Mnogo nam nedostaje.

Predgovor

Napisao sam prvi nacrt knjige "Efektivno korištenje C++" 1991. Kada je došlo vrijeme za drugo izdanje 1997. godine, značajno sam dopunio materijal, ali sam, ne želeći da osramotim čitaoce upoznate s prvim izdanjem, pokušao da zadrži postojeću strukturu: 48 od originalnih 50 pravila su u suštini ostala nepromijenjena. Ako uporedite knjigu sa kućom, onda je drugo izdanje bilo kao preuređenje- tapetiranje, farbanje u druge boje i zamena rasvetnih tela.

U trećem izdanju odlučio sam se za mnogo više. (Bio je trenutak kada sam poželeo da obnovim sve, počevši od temelja.) Jezik C++ se dosta promenio od 1991. godine, a svrha ove knjige je da identifikuje sve što je najvažnije i da to predstavi u obliku kompaktne zbirke preporuka - više nije ispunjavao set pravila formuliranih prije 15 godina. Godine 1991. bilo je razumno pretpostaviti da će programeri sa iskustvom u radu sa C preći na C ++. Sada, sa jednakom verovatnoćom, njima se mogu pripisati oni koji su ranije pisali na Javi ili C #. Godine 1991., nasljeđivanje i objektno orijentirano programiranje bili su novina za većinu programera. Sada su to dobro poznati koncepti, a područja koja ljudi trebaju dodatno razjasniti su izuzeci, obrasci i generičko programiranje. Godine 1991. niko nije čuo za obrasce dizajna. Sada, bez pominjanja njih, općenito je teško raspravljati softverski sistemi... Godine 1991. rad na formalnom C++ standardu je tek počinjao, sada je ovaj standard star već 8 godina, a u toku je rad na sljedećoj verziji.

Kako bih se prilagodio svim ovim promjenama, odlučio sam početi s blanko list i zapitao sam se: "Koji savjet da dam programerima koji vježbaju C++ u 2005. godini?" Rezultat je skup pravila uključenih u novo izdanje. Ova knjiga uključuje nova poglavlja o programiranju obrazaca i upravljanju resursima. U stvari, predlošci prolaze kao crvena nit kroz cijeli tekst, budući da je malo u modernom C ++ potpuno bez njih. Knjiga takođe uključuje materijal o programiranju sa izuzecima, obrascima dizajna i novim bibliotečkim alatima opisanim u Tehničkom izveštaju 1 (TR1) (o kome se govori u pravilu 54). Također je poznato da pristupi i tehnike koji dobro rade na jednonitnim sistemima možda nisu primjenjivi na višenitne sisteme. Više od polovine materijala u ovom izdanju su nove teme. Međutim, veliki dio temeljnih informacija iz drugog izdanja ostaje relevantan, pa sam pronašao način da ih ponovim u ovom ili onom obliku (pogledajte Dodatak B za korespondenciju između pravila drugog i trećeg izdanja).

Dao sam sve od sebe da ovu knjigu učinim što korisnijom, ali naravno ne mislim da je savršena. Ako vam se čini da se neka od gore navedenih pravila ne mogu smatrati univerzalno primjenjivima, da postoji bolji način za rješavanje formulisanog problema ili da rasprava o nekim tehnička pitanja nije dovoljno jasno, nepotpuno, može biti pogrešno, molim vas recite mi. Ako nađete greške bilo koje vrste - tehničke, gramatičke, tipografske, - bilo koje, - pišite mi o tome. Prilikom puštanja sljedećeg tiraža rado ću spomenuti sve koji mi skrenu pažnju na neki problem.

Uprkos činjenici da je u novom izdanju broj pravila povećan na 55, naravno, ne može se reći da su razmotrena sva i svakakva pitanja. Ali formulisanje skupa pravila kojih se treba pridržavati u gotovo svim aplikacijama teže je nego što se čini na prvi pogled. Ako imate bilo kakve sugestije o tome šta još uključiti, rado bih ih razmotrio.


Staford, Oregon, april 2005

Uvod

Jedno je učiti osnove jezika, i sasvim drugo - učenje dizajniranja i implementacije efektivnih programa. To se posebno odnosi na C++, poznat po svojim neobično bogatim mogućnostima i izražajnosti. Rad u C ++, kada se pravilno koristi, može biti zabavan. Širok spektar projekata može se direktno izraziti i efikasno implementirati. Pažljivo odabran i dobro implementiran skup klasa, funkcija i šablona pomoći će da program bude jednostavan, intuitivan, efikasan i praktički bez grešaka. Uz odgovarajuće vještine, pisanje efikasnih C++ programa uopće nije teško. Međutim, ako se koristi nepromišljeno, C ++ može proizvesti nerazumljiv, težak za održavanje i jednostavno netačan kod.

Svrha ove knjige je da vam pokaže kako da koristite C++ efikasno. Pretpostavljam da ste već upoznati sa C++ kao programski jezik, i takođe imati neko iskustvo sa tim. Skrećem vam pažnju na smjernice za korištenje ovog jezika, slijedeći koje će vaše programe učiniti razumljivim, lakim za održavanje, prenosivim, proširivim, efikasnim i izvođenjem prema očekivanjima.

Predloženi savjeti se mogu podijeliti u dvije kategorije: ukupna strategija dizajn i praktična upotreba odvojene jezičke konstrukcije. Diskusija o dizajnu ima za cilj da vam pomogne da odaberete između različitih pristupa rješavanju datog problema u C++. Da li da biram nasleđe ili šablone? Javno ili privatno nasljeđe? Zatvoreno nasljeđe ili sastav? Članske funkcije ili slobodne funkcije? Proći po vrijednosti ili po referenci? Važno je donijeti ispravnu odluku od samog početka, jer se posljedice lošeg izbora možda neće manifestirati na bilo koji način dok ne bude prekasno, a to će biti teško, dugotrajno i skupo ponoviti.

Čak i kada tačno znate šta želite da radite, može biti teško postići željene rezultate. Koju vrstu vrijednosti treba vratiti operator dodjeljivanja? Kada destruktor treba biti virtualan? Kako se ponaša novi operator ako ne može pronaći dovoljno memorije? Izuzetno je važno proraditi kroz ove detalje, jer ćete u suprotnom gotovo sigurno naići na neočekivano, pa čak i neobjašnjivo ponašanje programa. Ova knjiga će vam pomoći da izbjegnete ovakve situacije.

Naravno, ovu knjigu je teško imenovati kompletno vođenje u C++. Umjesto toga, to je zbirka od 55 savjeta (ili pravila) o tome kako poboljšati svoje programe i projekte. Svaki paragraf je manje-više nezavisan od ostalih, ali većina je unakrsno referencirana. Najbolji način da pročitate ovu knjigu je da počnete s pravilom koje vas najviše zanima, a zatim slijedite linkove da vidite kuda vas vode.

Ova knjiga takođe nije uvod u C++. U poglavlju 2, na primjer, govorim o tome kako pravilno implementirati konstruktore, destruktore i operatore dodjele, ali pretpostavljam da već znate šta ove funkcije rade i kako su deklarirane. Postoji mnogo C++ knjiga na ovu temu.

Target ovo knjige - ističu one aspekte C++ programiranja koji se često zanemaruju. Druge knjige opisuju različite dijelove jezika. Takođe objašnjava kako ih kombinovati jedno s drugim da biste dobili učinkovite programe. Druga izdanja govore o tome kako dobiti program za kompajliranje. A ova knjiga govori o tome kako izbjeći probleme koje kompajler ne može otkriti.

U isto vrijeme, ova knjiga je ograničena na standard C ++. Ovdje se koriste samo one jezičke karakteristike koje su opisane u službenom standardu. Prenosivost je ključno pitanje za ovu knjigu, pa ako tražite trikove specifične za platformu, pogledajte druga izdanja.

U ovoj knjizi nećete naći "Jevanđelje po C++" - jedini pravi put do idealnog C++ programa. Svako pravilo je preporuka za jedan ili drugi aspekt: ​​kako pronaći bolji dizajn, kako izbjeći tipične greške kako postići maksimalnu efikasnost, ali nijedna od tačaka nije univerzalno primjenjiva. Dizajn i razvoj softvera je složen zadatak na koji utiču ograničenja hardver, operativni sistem i aplikacije, tako da najbolje što mogu učiniti je da budem prisutan preporuke za poboljšanje kvaliteta programa.

Ako sistematski slijedite sve preporuke, malo je vjerovatno da ćete naići na najčešće zamke koje vas čekaju u C ++, ali postoje izuzeci od bilo kojeg pravila. Zato su objašnjenja data u svakom pravilu. Oni čine najvažniji dio knjige. Samo razumijevanjem onoga što leži u srcu određenog pravila možete odlučiti u kojoj mjeri ono odgovara vašem programu sa svojim inherentnim ograničenjima.

Najbolji način da koristite ovu knjigu jeste da razumete tajne ponašanja C ++, razumete zašto se ponaša na način na koji se ponaša i iskoristite njegovo ponašanje u svoju korist. Slijepa primjena u praksi svih navedenih pravila je potpuno neprikladna, ali u isto vrijeme ne treba postupati suprotno ovim savjetima bez posebnih razloga.

Terminologija

Postoji mali C++ vokabular kojim bi svaki programer trebao savladati. Sljedeći izrazi su dovoljno važni da ima smisla osigurati da ih razumijemo na isti način.

Najava(deklaracija) govori kompajleru ime i tip nečega, izostavljajući neke detalje. Oglasi izgledaju ovako:


extern int x; // deklaracija objekta

std :: size_t numDigits (int number); // deklaracija funkcije

class Widget; // deklaracija klase

šablon // deklaracija šablona

class GraphNode; // (pogledajte pravilo 42 o tome šta je "typename".


Imajte na umu da cijeli broj x nazivam "objekat" iako je ugrađena varijabla. Neki ljudi pod "objektima" podrazumijevaju samo varijable korisnički definiranih tipova, ali ja nisam jedan od njih. Također imajte na umu da funkcija numDigits () vraća tip std :: size_t, odnosno tip size_t iz std imenskog prostora. Ovo je imenski prostor u kojem se nalazi skoro sve iz C++ Standardne biblioteke. Međutim, pošto se standardna biblioteka C (tačnije C89) može koristiti i u C++ programu, simboli nasleđeni od C (kao što je size_t) mogu postojati u globalnom kontekstu, unutar std-a ili oboje, ovisno o tome koje su datoteke zaglavlja uključene u #include direktivu. Za ovu knjigu pretpostavljam da su datoteke zaglavlja C ++ uključene u #include. Zbog toga koristim std :: size_t, a ne samo size_t. Kada spomenem komponente standardne biblioteke izvan koda, obično izostavljam std referencu, pod pretpostavkom da znate da se stvari kao što su size_t, vektor i cout nalaze u std imenskom prostoru. U primjere programa uvijek uključujem std, jer se inače kod neće kompajlirati.

Usput, size_t je samo sinonim definiran typedef direktivom za neke od nepotpisanih tipova koji se koriste u C ++ za različite vrste brojači (na primjer, broj znakova u char * stringovima, broj elemenata u STL kontejnerima, itd.). To je također tip koji prihvaćaju operatorske funkcije u vektorima, nizovima i nizovima. Pratit ćemo ovu konvenciju kada definiramo vlastite operatorske funkcije u pravilu 3.

Bilo koja deklaracija funkcije specificira njenu potpis, odnosno tipovi parametara i povratna vrijednost. Možemo reći da je potpis funkcije njen tip. Dakle, potpis funkcije numDigits je std :: size_t (int), drugim riječima, to je “funkcija koja uzima int i vraća std :: size_t”. Zvanična definicija"Potpisi" u C ++ ne uključuju tip povratka funkcije, ali za ovu knjigu će nam biti zgodno pretpostaviti da je to još uvijek dio potpisa.

Definicija(definicija) govori kompajleru detalje koji su izostavljeni iz deklaracije. Za objekt, definicija je mjesto gdje kompajler dodjeljuje memoriju za njega. Za funkciju ili predložak funkcije, definicija sadrži tijelo funkcije. Definicija klase ili predložak klase navodi njene članove:


int x; // definicija objekta

std :: size_t numDigits (int number) // definicija funkcije

(// (ova funkcija vraća broj

std :: size_t digitsSoFar = 1; // decimalna mjesta u svom parametru)

dok ((broj / = 10)! = 0) ++ digitsSoFar;

return digitsSoFar;

class Widget (// definicija klase

šablon // definicija šablona

klasa GraphNode (


Inicijalizacija(inicijalizacija) je proces inicijalizacije objekta. Za objekte korisnički definiranih tipova, inicijalizaciju izvode konstruktori. Zadani konstruktor(podrazumevani konstruktor) je konstruktor koji se može pozvati bez argumenata. Takav konstruktor ili nema nikakve parametre ili ima zadanu vrijednost za svaki parametar:


A (); // zadani konstruktor

eksplicitno B (int x = 0; bool b = istina); // zadani konstruktor,

// ključna riječ "eksplicitna"

eksplicitno C (int x); // ovo nije konstruktor po

// default


Konstruktori klasa B i C su deklarisani sa eksplicitnom ključnom reči. Ovo onemogućava njihovu upotrebu za implicitne konverzije, iako ne sprječava njihovu upotrebu ako je konverzija eksplicitno specificirana:


void doSomething (B bObject); // funkcija uzima objekt tipa B

B bObj1; // objekt tipa B

doSomething (bObj1); // ok, B se prosljeđuje na doSomething

B bObj (28); // ok, kreira B od cijelog broja 28

// (parametar bool je po defaultu true)

uradi nešto (28); // greška! doSomething prihvata B,

// nije int, i nema implicitnog

// konverzije iz int u B

uradi nešto (B (28)); // ok, koristi se konstruktor

// B za eksplicitnu konverziju (casting)

// int u B (pogledajte pravilo 27 za informacije

// o tipovima)


Konstruktori koji su deklarirani eksplicitno općenito su poželjniji jer sprječavaju kompajlere da izvode implicitne (često neželjene) konverzije tipa. Osim ako ne postoji dobar razlog za korištenje konstruktora u implicitnim konverzijama, uvijek ih proglašavam eksplicitnim. Savjetujem vam da se pridržavate istog principa.

Imajte na umu da je u prethodnom primjeru uloga istaknuta. Nastavit ću koristiti ovaj naglasak da naglasim važnost prezentiranog materijala. (Ističem i brojeve poglavlja, ali to je samo zato što mislim da izgleda slatko.)

Konstruktor kopiranja(konstruktor kopiranja) se koristi za inicijalizaciju objekta vrijednošću drugog objekta istog tipa, i operator dodjeljivanja kopiranja(operator dodjeljivanja kopiranja) se koristi za kopiranje vrijednosti jednog objekta u drugi - istog tipa:


Widget (); // zadani konstruktor

Widget (const Widget & rhs); // konstruktor kopiranja

Widget & operator = (const Widget & rhs); // kopiraj operator dodjele

Widget w1; // pozivamo zadani konstruktor

Widget w2 (w1); // pozivamo konstruktor kopiranja

w1 = w2; // pozivamo operatora dodjele

// copy


Budite oprezni kada vidite konstrukciju nalik zadatku, jer se sintaksa "=" također može koristiti za pozivanje konstruktora kopiranja:


Widget w3 = w2; // pozivamo konstruktor kopiranja!


Na sreću, konstruktor kopiranja je lako razlikovati od zadatka. Ako je definiran novi objekt (kao w3 u posljednjoj klauzuli), tada se mora pozvati konstruktor, to ne može biti dodjela. Ako se ne kreira novi objekat (kao u "w1 = w2"), tada se konstruktor ne primenjuje i ovo je dodeljivanje.

Konstruktor kopiranja je posebno važan jer definira kako se objekt prosljeđuje po vrijednosti. Na primjer, razmotrite sljedeći isječak:


bool hasAcceptableQuality (widget w);

if (hasAcceptableQuality (aWidget)) ...


Parametar w se prosljeđuje po vrijednosti funkciji hasAcceptableQuality, tako da je u gornjem primjeru poziv aWidget kopiran u w. Kopiranje vrši konstruktor kopiranja iz klase Widget. Općenito prolazno po vrijednosti znači poziv konstruktoru kopiranja. (Ali, strogo govoreći, prosljeđivanje prilagođenih tipova po vrijednosti je loša ideja... Obično je najbolja opcija proći putem reference na konstantu; pogledajte stavku 20 za detalje.)

STL- Standard Template Library je dio standardne biblioteke koji se bavi kontejnerima (tj. vektor, lista, skup, mapa, itd.), iteratorima (tj. vektor :: iterator, set :: iterator, itd.) itd.), algoritmima (tj. for_each, find, sort, itd.) i sve povezane funkcionalnosti. Veoma se koristi funkcionalni objekti(funkcijski objekti), odnosno objekti koji se ponašaju kao funkcije. Takvi objekti su predstavljeni klasama u kojima je operator operatora poziva () preopterećen. Ako niste upoznati sa STL-om, trebat će vam, pored ove knjige, i neki pristojan priručnik na ovu temu, jer je STL biblioteka toliko zgodna da bi bilo neoprostivo ne iskoristiti njene prednosti. Treba samo da počnete da radite sa njom, i sami ćete to osetiti.

Za programere koji su na C++ došli iz jezika poput Java ili C#, koncept nedefinisano ponašanje. Iz raznih razloga, ponašanje nekih konstrukcija u C++ je zaista nedefinisano: ne možete sa sigurnošću predvidjeti šta će se desiti tokom izvršavanja. Evo dva primjera ove vrste:


int * p = 0; // p je nulti pokazivač

char name = “Daria” // ime je niz dužine 6 (ne zaboravite na

// zadnja nula!)

char c = ime; // specificiranje pogrešnog indeksa niza

// pokreće nedefinirano ponašanje


Kako bi naglasili da se rezultati nedefiniranog ponašanja ne mogu predvidjeti i da mogu biti prilično neugodni, iskusni C++ programeri često kažu da programi s nedefiniranim ponašanjem mogu obrisati sadržaj tvrdog diska. Istina je: takav program možda obrišite svoje HDD, ali možda neće. Veća je vjerovatnoća da će se ponašati drugačije, ponekad u redu, ponekad pada, a ponekad samo daje netačne rezultate. Mudri C++ programeri pridržavaju se pravila izbjegavanja nedefiniranog ponašanja. Kroz ovu knjigu vam pokazujem kako se to radi na mnogim mjestima.

Drugi termin koji može zbuniti programere koji su došli sa drugih jezika je interfejs. U Javi i. NET-kompatibilni jezici, interfejsi su deo jezika, ali C++ nema ništa slično, iako se Pravilo 31 bavi nekim aproksimacijom. Kada koristim izraz "sučelje", obično mislim na potpise funkcija, dostupne članove klase ("javni interfejs", "zaštićeni interfejs", " zatvoreni interfejs") Ili izrazi dozvoljeni kao parametri tipa za predloške (pogledajte stavku 41). Odnosno, pod interfejsom mislim na opšti koncept dizajna.

Koncept kupac Da li je nešto ili neko ko koristi kod koji pišete (obično preko interfejsa). Tako, na primjer, klijenti funkcije su njeni korisnici: dijelovi koda koji pozivaju funkciju (ili uzimaju njenu adresu), kao i ljudi koji pišu i održavaju takav kod. Klijenti klase ili predloška su dijelovi programa koji koriste tu klasu ili šablon, kao i programeri koji pišu ili održavaju te dijelove. Kada su u pitanju klijenti, obično mislim na programere jer mogu biti zavedeni ili frustrirani loše dizajniranim interfejsima. Kod koji pišu nema takve emocije.

Možda niste navikli razmišljati o klijentima, ali pokušaću da vas uvjerim u potrebu da im život učinite što lakšim. Uostalom, i sami ste klijent softvera koji je neko drugi razvio. Na kraju krajeva, želite da vam njeni autori olakšaju rad? Osim toga, prije ili kasnije ćete se naći u poziciji da i sami postanete klijent vlastitog koda (tj. koristit ćete kod koji napišete) i tada ćete cijeniti da prilikom dizajniranja sučelja morate zadržati imajući u vidu interese klijenata.

U ovoj knjizi često se fokusiram na razliku između funkcija i predložaka funkcija, te između klasa i predložaka klasa. To nije slučajno, jer ono što je tačno za jednog često je tačno i za drugog. U situacijama kada to nije slučaj, pravim razliku između klasa, funkcija i šablona iz kojih su klase i funkcije izvedene.

Konvencija imenovanja

Pokušao sam odabrati smislena imena za objekte, klase, funkcije, šablone, itd., ali vam semantika nekih imena koja sam smislila možda neće biti jasna. Na primjer, često koristim nazive lhs i rhs za parametre. Ovo se odnosi na "lijevu stranu" i "desnu stranu", respektivno. Ova imena se obično koriste u funkcijama koje implementiraju binarne operatore, odnosno operator == i operator *. Na primjer, ako su a i b objekti koji predstavljaju racionalne brojeve, i ako se objekti klase Rational mogu pomnožiti nečlanom funkcijom operatora * () (sličan slučaj je opisan u pravilu 24), tada izraz



je ekvivalentno pozivanju funkcije:


operator * (a, b);


U pravilu 24, deklariram operator * ovako:


const Rational operator * (const Rational & lhs, const Rational & rhs);


Kao što vidite, lijevi operand - a - unutar funkcije se zove lhs, a desni - b - rhs.

Za funkcije člana, argument na lijevoj strani iskaza je predstavljen pokazivačem this i jedinim preostalim parametrom koji ponekad nazivam rhs. Možda ste to primijetili u deklaracijama nekih funkcija člana Widgeta u gornjim primjerima. "Vidžet" ne znači ništa. To je samo ime koje ponekad koristim da nekako imenujem primjer klase. Nema nikakve veze sa kontrolama (widgetima) koji se koriste grafički interfejsi(GUI).

Često imenujem pokazivače slijedeći konvenciju da se pokazivač na objekt tipa T zove pt ("pokazivač na T"). Evo nekoliko primjera:


Widget * pw; // pw = pokazivač na Widget

Avion * pa; // pa = pokazivač na avion

klasa GameCharacter;

GameCharacter * pgc; // pgc = pokazivač na GameCharacter


Slična konvencija se primjenjuje na veze: rw može biti Widget veza, a ra može biti Airplane link.

Ponekad koristim ime mf da imenujem funkciju člana.

Multithreading

U samom jeziku C ++ nema pojma o nitima, a zapravo ni o kakvim mehanizmima paralelnog izvršavanja. Isto važi i za standardnu ​​biblioteku C ++. Drugim riječima, sa stanovišta C ++, višenitni programi ne postoje.

Međutim, jesu. Iako ću se u ovoj knjizi prvenstveno fokusirati na standardni, prenosivi C++, nemoguće je zanemariti činjenicu da je sigurnost niti zahtjev sa kojim se suočavaju mnogi programeri. Uvažavajući ovaj sukob između standardnog C++ i stvarnosti, napomenuću gdje dotične konstrukcije mogu uzrokovati probleme pri radu u višenitnom okruženju. Nemojte misliti da će vas ova knjiga naučiti višenitnom C++ programiranju. Ne sve. Pogledao sam uglavnom jednonitne aplikacije, ali nisam zanemario postojanje višenitnog rada i pokušao sam primijetiti kada bi programeri koji pišu višenitne programe trebali oprezno slijediti moj savjet.

Ako niste upoznati s konceptom višenitnog rada i niste zainteresirani za ovu temu, onda možete zanemariti napomene vezane za to. Inače, imajte na umu da moji komentari nisu ništa drugo nego skromni nagovještaj onoga što trebate znati ako ćete koristiti C++ za pisanje programa s više niti.

TR1 i Boost biblioteke

U ovoj knjizi ćete vidjeti reference na biblioteke TR1 i Boost. Svaki od njih ima posebno pravilo (54 - TR1 i 55 - Boost), ali se, nažalost, nalaze na samom kraju knjige. Možete ih pročitati odmah ako želite, ali ako više volite da čitate knjigu po redu, a ne od kraja, onda će vam sljedeće napomene pomoći da shvatite o čemu je riječ:

TR1 ("Tehnički izvještaj 1") je specifikacija nove funkcionalnosti koja je dodana standardna biblioteka C ++. Uokviren je novim predlošcima klasa i funkcijama dizajniranim da implementiraju hash tablice, pametne pokazivače s brojanjem referenci, regularne izraze i još mnogo toga. Sve TR1 komponente su u tr1 imenskom prostoru, koji je ugniježđen ispod std imenskog prostora.

Boost je organizacija i web stranica (http://boost.org) koja nudi prenosive, dobro testirane C++ biblioteke otvorenog koda. izvorni kod... Veći dio TR1 se nadograđuje na rad koji je obavio Boost, i dok proizvođači kompajlera ne uključe TR1 u C++ distribucije, Boost web stranica će ostati glavni izvor implementacije TR1 za programere. Boost pruža više od onoga što je uključeno u TR1, ali je svejedno dobro znati o tome.

Naviknite se na C++

Bez obzira na iskustvo u programiranju, navikavanje na C ++ će potrajati. To je moćan jezik sa vrlo širok raspon mogućnosti, ali da biste ih efikasno iskoristili, morate malo promijeniti svoj način razmišljanja. Knjiga je osmišljena da vam u tome pomogne, ali neka pitanja su važnija, neka manje, a ovo poglavlje je posvećeno najvažnijim stvarima.

Pravilo 1: Tretirajte C ++ kao konglomerat jezika

U početku je C ++ bio samo C jezik sa dodanim nekim objektno orijentisanim karakteristikama. Čak i originalni C++ naziv ("C sa klasama") odražava ovaj odnos.

Kako je jezik sazrevao, rastao i razvijao se, uključivao je programske ideje i strategije koje su prevazilazile C sa klasama. Izuzeci su zahtijevali drugačiji pristup strukturiranju funkcija (vidi pravilo 29). Predlošci su promijenili način na koji dizajniramo programe (vidi tačku 41), a STL je uveo pristup proširivosti kakav niko drugi nije mogao zamisliti.

Danas je C++ jezik programiranje sa više paradigmi, podržavaju proceduralno, objektno orijentisano, funkcionalno, generičko i metaprogramiranje. Ova moć i fleksibilnost čine C++ neuporedivim alatom, ali može biti zbunjujući. Svaka preporuka za “ ispravnu primjenu»Postoje izuzeci. Kako pronaći značenje u takvom jeziku?

Najbolje je razmišljati o C++ ne kao o jednom jeziku, već kao o konglomeratu međusobno povezanih jezika. Unutar zasebnog podjezika, pravila su prilično jednostavna, razumljiva i lako pamtljiva. Međutim, kada pređete s jednog podjezika na drugi, pravila se mogu promijeniti. Da biste vidjeli smisao u C ++, morate prepoznati njegove glavne podjezike. Na sreću, postoje samo četiri:

C. U svojim dubinama, C ++ je i dalje baziran na C. Blokovi, izjave, predprocesor, ugrađeni tipovi podataka, nizovi, pokazivači, itd. svi potiču iz C. U mnogim slučajevima, C ++ pruža naprednije mehanizme za rješavanje određenih probleme, nego C (na primjer, vidi pravilo 2 - alternativa predprocesoru i 13 - korištenje objekata za upravljanje resursima), ali kada počnete raditi s dijelom C++ koji ima analoge u C-u, shvatit ćete da pravila efikasnog programiranja odražavaju ograničeniju prirodu jezika C: bez šablona, ​​bez izuzetaka, bez preopterećenja itd.

Objektno orijentisan C++. Ovaj dio C++ predstavlja ono što je bio "C sa klasama", uključujući konstruktore i destruktore, enkapsulaciju, nasljeđivanje, polimorfizam, virtualne funkcije(dinamičko povezivanje) itd. Ovo je dio C ++ na koji je u najviše primjenjuju se klasična pravila objektno orijentisanog dizajna.

C ++ sa šablonima. Ovaj dio C++ naziva se generičko programiranje i većina programera malo zna o njemu. Predlošci sada prožimaju C ++ odozdo prema gore i znak je dobre programske prakse uključiti konstrukcije nezamislive bez predložaka (na primjer, pogledajte pravilo 46 o konverzijama tipova prilikom pozivanja šablonskih funkcija). Zapravo, predlošci su, zahvaljujući svojoj moći, iznjedrili potpuno novu programsku paradigmu: metaprogramiranje šablona(metaprogramiranje šablona - TMP). Pravilo 48 pruža pregled TMP-a, ali osim ako niste tvrdoglavi fanatik šablona, ​​nemate razloga da ga previše razmišljate. TMP nije jedna od najčešćih tehnika C++ programiranja.

STL. STL je, naravno, biblioteka šablona, ​​ali veoma specijalizovana. Konvencije koje pravi o kontejnerima, iteratorima, algoritmima i funkcionalnim objektima lijepo funkcionišu zajedno, ali predlošci i biblioteke mogu se izgraditi drugačije. Kada radite sa STL-om, morate slijediti njegove konvencije.

Imajte na umu ova četiri podjezika i nemojte se iznenaditi ako se nađete u situaciji u kojoj efikasnost programiranja zahtijeva da promijenite svoju strategiju kada prelazite s jednog podjezika na drugi. Na primjer, za ugrađene tipove (C stil) prosljeđivanje parametara po vrijednosti u opšti slučaj je efikasnije od prosljeđivanja po referenci, ali ako programirate u objektno orijentiranom stilu, tada prosljeđivanje putem reference na konstantu obično postaje efikasnije zbog prisutnosti korisnički definiranih konstruktora i destruktora. Ovo posebno važi za podjezik "C ++ sa predlošcima", jer tamo obično ne znate unapred ni sa kojim tipom objekata imate posla. Ali sada ste prešli na korištenje STL-a i opet staro C pravilo o prosljeđivanju vrijednosti postaje relevantno, jer se iteratori i funkcijski objekti modeliraju preko C pokazivača. (Za detalje o odabiru metode za prosljeđivanje parametara, pogledajte pravilo 20.)

Dakle, C++ nije homogen jezik sa jednim skupom pravila. To je konglomerat podjezika, svaki sa svojim vlastitim konvencijama. Ako imate na umu ove podjezike, otkrit ćete da je C++ mnogo lakši za razumijevanje.

Stvari koje treba zapamtiti

Pravila za efikasno programiranje se menjaju u zavisnosti od dela C++ koji koristite.

Pravilo 2: Preferirajte const, enum i inline u odnosu na #define

Bilo bi bolje nazvati ovo pravilo "Kompajler je poželjniji od predprocesora", pošto se #define često uopće ne pominje kao C++ jezik. To je problem. Pogledajmo jednostavan primjer; pokušaj da napišeš nešto poput:


#define ASPECT_RATIO 1.653


Simboličko ime ASPECT_RATIO može ostati nepoznato kompajleru ili ga pretprocesor može ukloniti prije nego što kompajler obradi kod. Ako se to dogodi, ime ASPECT_RATIO neće biti uključeno u tablicu simbola. Zbog toga, tokom kompilacije, dobićete grešku (u poruci će se pominjati vrednost 1.653, a ne ASPECT_RATIO). Ovo će izazvati zabunu. Ako je naziv ASPECT_RATIO definiran u zaglavlju koji niste napisali, tada nećete ni znati odakle dolazi vrijednost od 1.653 i potrošit ćete dosta vremena tražeći odgovor. Isti problem se može pojaviti prilikom otklanjanja grešaka jer ime koje odaberete neće biti u tabeli simbola.

Rješenje je zamijeniti makro konstantom:


const double AspectRatio = 1,653; // imena napisana velikim slovima,

// obično se koristi za makroe,

// pa smo odlučili da ga promijenimo


Kao jezička konstanta, AspectRatio je vidljiv kompajleru i prirodno se nalazi u tabeli simbola. Osim toga, korištenje konstante s pomičnim zarezom (kao u ovom primjeru) generira kompaktniji kod od korištenja #define. Činjenica je da predprocesor, slijepo zamjenjujući vrijednost 1.653 umjesto ASPECT_RATIO makroa, kreira mnogo kopija 1.653 u objektnom kodu, dok korištenje konstante nikada neće generirati više od jedne kopije ove vrijednosti.

Prilikom zamjene # definisati konstante dvije stvari koje treba zapamtiti posebnim slučajevima... Prvi se odnosi na konstantne pokazivače. Budući da se definicije konstante obično postavljaju u datoteke zaglavlja (gdje im pristupaju mnogi različiti izvorne datoteke), važno je da pokazivač je deklariran sa ključnom riječi const, uz const deklaraciju na šta ukazuje. Na primjer, da biste deklarirali konstantni niz tipa char * u datoteci zaglavlja, treba napisati riječ const dva puta:


const char * const authorName = “Scott Meyers”;


Za više informacija o prirodi i upotrebi riječi const, posebno u vezi s pokazivačima, pogledajte Pravilo 3. Ali već sada vrijedi podsjetiti da su objekti tipa string obično poželjniji od svojih predaka - nizova tipa char *, pa je bolje je definirati autorsko ime ovako:


const std :: string authorName (“Scott Meyers”);


Druga napomena se odnosi na konstante deklarirane unutar klase. Da biste ograničili opseg konstante na klasu, morate je učiniti članom klase, a kako biste osigurali da postoji samo jedna kopija konstante, morate je učiniti statičkičlan:


klasa GamePlayer (

static const int NumTurns = 5; // konstantna deklaracija

int scores; // koristeći konstantu


Ono što vidite gore je najava NumTurns, a ne njegova definicija. Obično C++ od vas zahtijeva da date definiciju za sve što koristite, ali konstante deklarirane u klasi koje su statične i ugrađenog tipa (tj. cijeli brojevi, char, boolean) su izuzetak od pravila. Sve dok ne pokušavate da dobijete adresu takve konstante, možete je deklarisati i koristiti bez davanja definicije. Ako trebate dobiti adresu, ili ako vaš prevodilac insistira na definiciji, možete napisati nešto poput ovoga:


const int GamePlayer :: NumTurns; // definicija NumTurns; vidi ispod,

// zašto vrijednost nije navedena


Postavite ovaj kod u datoteku implementacije, a ne u datoteku zaglavlja. Pošto je početna vrijednost konstante klase predstavljena tamo gdje je deklarirana (to jest, NumTurns je inicijaliziran na 5 kada je deklariran), nema potrebe specificirati početnu vrijednost u tački definicije.

Uzgred, imajte na umu da nije moguće deklarirati konstantu u klasi koristeći #define, jer #define nema opseg. Jednom kada je makro definiran, on ostaje na snazi ​​za ostatak kompajliranog koda (osim ako se #undef ne nađe negdje ispod). To znači da direktiva #define nije primjenjiva ne samo za deklariranje konstanti u klasi, već se općenito ne može koristiti za pružanje bilo kakve enkapsulacije, odnosno nemoguće je dati značenje izrazu "private #define". U isto vrijeme, konstantni podaci o članovima mogu biti enkapsulirani, na primjer NumTurns.

Stariji prevodioci možda ne podržavaju gore prikazanu sintaksu jer ranijim verzijama jezika nije bilo dozvoljeno da postavljaju vrednosti statičkih članova klase tokom deklaracije. Štaviše, inicijalizacija u klasi bila je dozvoljena samo za cjelobrojne tipove i za konstante. Ako gornja sintaksa ne radi, početnu vrijednost treba navesti u definiciji:


klasa CostEstimate (

static const double FudgeFactor; // deklaracija statičke konstante

... // klasa - smještena u datoteku zaglavlja

const double // definicija statičke konstante

CostEstimate :: FudgeFactor = 1,35; // klasa - smještena u datoteku implementacije


Obično ništa drugo nije potrebno. Jedini izuzetak se stvara kada je potrebna konstanta za kompajliranje klase. Na primjer, kada deklariše niz GamePlayer :: rezultate, kompajler treba da zna veličinu niza. Da biste radili s kompajlerom koji greškom zabranjuje inicijalizaciju statičkih cjelobrojnih konstanti unutar klase, možete koristiti tehniku ​​poznatu kao trik nabrajanja. Zasnovan je na činjenici da se nabrojane varijable mogu koristiti tamo gdje se očekuju int vrijednosti, pa se GamePlayer može definirati ovako:


klasa GamePlayer (

enum (NumTurns = 5); // "trik sa nabrajanjem" - čini od

// NumTurns karakter s vrijednošću 5

int scores; // u redu


Ovu tehniku ​​vrijedi poznavati iz nekoliko razloga. Prvo, ponašanje trika nabrajanja je u nekim aspektima više kao #define nego konstantno, a ponekad je to upravo ono što želite. Na primjer, možete dobiti adresu konstante, ali ne možete dobiti adresu nabrajanja, kao što ne možete dobiti adresu #define. Ako želite spriječiti dobivanje adrese ili reference na neku cjelobrojnu konstantu, onda je korištenje enuma dobar način da nametnete takvo ograničenje. (Pogledajte pravilo 18 za više informacija o podržavanju ograničenja dizajna tehnikama kodiranja.) Osim toga, dok dobri prevodioci ne dodeljuju memoriju za konstantne celobrojne objekte (osim ako ne kreirate pokazivač ili referencu objekta), manje sofisticirani prevodioci to mogu da urade i verovatno vam ne treba. Kao i #define, enumovi nikada neće uzrokovati ovu vrstu neželjene dodjele memorije.

Drugi razlog da znate o triku nabrajanja je čisto pragmatičan. Koristi se u mnogim programima, tako da morate biti u stanju prepoznati ovaj trik kada naiđete na njega. Uopšteno govoreći, ova tehnika je osnovna tehnika koja se koristi u metaprogramiranju šablona (vidi tačku 48).

Vratimo se na pretprocesor. Još jedna uobičajena zloupotreba direktive #define je kreiranje makroa koji izgledaju kao funkcije, ali nisu opterećeni dodatnim troškovima poziva funkcija. Ispod je makro koji poziva neku funkciju f s argumentom jednakim maksimalno dvije vrijednosti:


// pozivamo f, prenoseći mu maksimum a i b

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


Toliko je nedostataka u ovoj liniji da nije sasvim jasno odakle početi.

Kad god pišete ovakav makro, morate zapamtiti da svi argumenti moraju biti zatvoreni u zagradama. U suprotnom, rizikujete da naiđete na problem kada ga neko nazove sa izrazom kao argumentom. Ali čak i ako dobro shvatite, pogledajte koje se čudne stvari mogu dogoditi:


int a = 5, b = 0;

CALL_WITH_MAX (++ a, b); // a se povećava dvaput

CALL_WITH_MAX (++ a, b + 10); // a se povećava jednom


Šta se dešava unutar max-a zavisi od toga sa čime se poredi!

Srećom, ne morate da trpite ponašanje koje je protivno vašoj uobičajenoj logici. Postoji metod za postizanje iste efikasnosti kao i korišćenjem pretprocesora. Ali pruža i predvidljivo ponašanje i kontrolu nad tipovima argumenata (što je tipično za obične funkcije). Ovo se postiže korištenjem inline predloška funkcije (vidi pravilo 30):


inline void callWithMax (const T & a, const T & b) // Otkad ne znamo

(// šta je T, onda prolazimo

) // vidi paragraf 20


Ovaj šablon generiše čitavu porodicu funkcija, od kojih svaka uzima dva argumenta istog tipa i poziva f sa najvećim od njih. Nema potrebe za stavljanjem zagrada oko parametara unutar tijela funkcije, nema potrebe da brinete o procjeni parametara mnogo puta itd. Štaviše, pošto je callWithMax prava funkcija, podliježe pravilima opsega i kontrole pristupa. Na primjer, možete govoriti o ugrađenoj funkciji koja je privatni član klase. Nemoguće je ovako nešto opisati koristeći makro.

Prisustvo const, enum i inline drastično smanjuje potrebu za pretprocesorom (posebno za #define), ali je ne eliminiše u potpunosti. Direktiva #include ostaje suštinska, a # ifdef / # ifndef nastavlja da igra važnu ulogu u kontroli kompilacije. Još nije vrijeme za odbacivanje pretprocesora, ali svakako vrijedi razmisliti kako ga se riješiti u budućnosti.

Stvari koje treba zapamtiti

Za jednostavne konstante, direktiva #define bi trebala imati prednost u odnosu na konstantne objekte i enumeracije.

Umjesto makronaredbi koje oponašaju funkcije, definirane putem #define, bolje je koristiti ugrađene funkcije.

Pravilo 3: Koristite const gdje god je to moguće

Zgodna stvar kod modifikatora const je to što nameće određeno semantičko ograničenje: dati objekat ne smije biti modificiran, a kompajler će primijeniti ovo ograničenje. const vam omogućava da kažete kompajleru i programerima da određena vrijednost treba ostati nepromijenjena. U svim takvim slučajevima, morate to eksplicitno navesti, pozivajući kompajlera da vam pomogne i na taj način osiguravajući da ograničenje nije prekršeno.


Ova sintaksa nije tako strašna kao što se čini. Ako se riječ const pojavi lijevo od zvjezdice, konstanta je ono na što pokazuje pokazivač; ako je desno, onda je sam pokazivač konstantan. Konačno, ako se riječ const pojavljuje na obje strane, tada su obje konstantne.

Bilješke (uredi)

Postoji ruski prijevod: Sutter Coat of arms. Rješavanje složenih problema u C ++. Izdavačka kuća "Williams", 2002 (napomena urednika).

Postoji ruski prijevod: Design Patterns. SPb .: Petar (napomena urednika).

Kraj besplatnog probnog isječka.

  • Stranice:
    , ,
  • Recenzije trećeg izdanja
    Efikasna upotreba C++

    Knjiga Scotta Meyersa Efikasno korištenje C ++, treće izdanje- je koncentracija programskog iskustva - iskustvo koje bi vam bez njega skupo donijelo. Ova knjiga je odličan izvor koji preporučujem svima koji profesionalno pišu C++.

    Peter Dulimov, ME, inženjer, Jedinica za evaluaciju i istraživanje, NAVSYSCOM, Australija

    Treće izdanje ostaje najbolja knjiga o tome kako spojiti sve delove C ++ da bi se kreirali efikasni i konzistentni programi. Ako se prijavljujete za C++ programera, trebali biste to pročitati.

    Eric Nagler, konsultant, trener i autor Learning C++

    Prvo izdanje ove knjige bilo je jedno od malog (vrlo malog) broja knjiga koje su mi pomogle da značajno poboljšam svoj nivo profesionalnog programera softvera. Kao i druge knjige iz ove serije, pokazala se kao praktična i laka za čitanje, ali je sadržavala i mnogo važnih savjeta. „Efektivno korišćenje C ++ ", treće izdanje, nastavlja ovu tradiciju. C++ je veoma moćan programski jezik. Ako C pruža konopac za penjanje na vrh planine, onda je C ++ čitava prodavnica u kojoj su razni ljudi spremni da vam pomognu da vežete čvorove na ovom užetu. Savladavanje gradiva iz ove knjige definitivno će povećati vašu sposobnost da efikasno koristite C++ bez umiranja od stresa.

    Jack W. Reeves, izvršni direktor, Bleading Edge Software Technologies

    Svaki novi programer koji se pridruži mom timu odmah dobija zadatak da pročita ovu knjigu.

    Michael Lancetta, vodeći softverski inženjer

    Pročitao sam prvo izdanje Efikasno korištenje C++ prije otprilike 9 godina i ova knjiga je odmah postala jedna od mojih omiljenih C++ knjiga. Po mom mišljenju, treće izdanje knjige Efikasno korišćenje C++ ostaje obavezno čitanje za svakoga ko želi efikasno programirati na C++. Živjet ćemo u boljem svijetu ako C++ programeri pročitaju ovu knjigu prije nego što napišu prvi red profesionalnog koda.

    Danny Rabbani, softverski inženjer

    Prvo izdanje Skota Mejersa Efektivno korišćenje C ++ stiglo mi je kada sam bio prosečan programer i trudio sam se da uradim najbolje što sam mogao. I to je bio spas! Otkrio sam da je Meyersov savjet praktično koristan i djelotvoran, da će 100% ispuniti ono što obećava. Treće izdanje pomaže u praktičnoj upotrebi C ++ pri radu na modernim ozbiljnim softverskim projektima, pružajući informacije o najnovijim karakteristikama i mogućnostima jezika. Sa zadovoljstvom sam otkrio da u trećem izdanju knjige mogu pronaći mnogo novih i zanimljivih stvari za sebe, koje, kako mi se činilo, jako dobro poznajem.

    Michael Topek, tehnički menadžer programa

    Ovaj autoritativni vodič Scott Meyersa, C++ gurua, namijenjen je svima koji žele koristiti C++ bezbedno i efikasno, ili koji prelaze na C++ sa bilo kog drugog objektno orijentisanog jezika. Ova knjiga sadrži vrijedne informacije predstavljene jasnim, sažetim, zabavnim i pronicljivim stilom.

    Siddhartha Karan Singh, programer softvera

    Priznanja

    Knjiga "Upotreba C ++ Efektivno" postoji već 15 godina, a ja sam počeo da učim C ++ oko 5 godina pre nego što sam je napisao. Dakle, rad na ovom projektu traje već oko 20 godina. Za to vrijeme dobio sam želje, komentare, ispravke, a ponekad i ogromna zapažanja od stotina (hiljada?) ljudi. Svaki od njih doprinio je razvoju "Efektivnog korištenja C ++". Svima sam im zahvalan.

    Odavno sam odustao od pokušaja da se sjetim gdje i šta sam sam naučio, ali ne mogu a da ne spomenem jedan izvor, jer ga stalno koristim. To su Usenet diskusione grupe, posebno comp.lang.c ++.Moderated i comp.std.c++. Mnoga pravila u ovoj knjizi (možda većina) rezultat su razmišljanja o tehničkim idejama o kojima se raspravlja u ovim grupama.

    Steve Dewhurst mi je pomogao u odabiru novog materijala za treće izdanje knjige. Pravilo 11 preuzima ideju kopiranja i zamjene implementacije operatora = iz bilješki Herba Suttera, Problem 13 iz njegove knjige Exceptional C++ (Addison-Wesley, 2000). Ideja o preuzimanju resursa kao inicijalizacije (pravilo 13) dolazi iz Programskog jezika C++ (Addison-Wesley, 2002) Bjarnea Stroustrupa. Ideja koja stoji iza Pravila 17 preuzeta je iz odjeljka "Najbolje prakse" na Boost shared_ptr web-mjestu (http://boost.org/libs/ smart_ptr / shared_ptr.htm # BestPractices) i prerađena na osnovu materijala u problemu 21 u knjizi Herb Sutter, "Izuzetniji C++" (Addison-Wesley, 2002). Pravilo 29 inspirisano je opsežnim istraživanjem ove teme Herba Suttera u Izuzetnim C++ problemima 8-19, Izuzetnijim C++ problemima 17-23 i Iznimnim C++ problemima 11-13. Stil ”(Addison-Wesley, 2005) . David Abrahams mi je pomogao da bolje razumijem tri principa osiguravanja sigurnosti izuzetaka. Idiom nevirtuelnog interfejsa (NVI) u Pravilu 35 preuzet je iz Sutterove kolone "Virtualnost" u C / C ++ Users Journalu iz septembra 2001. godine. Metoda šablona i obrasci dizajna strategije koji se spominju u istom pravilu preuzeti su iz Design Patterns (Addison-Wesley, 1995) Ericha Gamme, Richarda Helma, Ralpha Johnsona (Ralf Johnson i John Vlissides). Ideja za idiom NVI u pravilu 37 potekla je od Hendrika Schobera. Doprinos Davida Smallberga implementaciji skupa opisanoj u točki 38. Opažanje u točki 39 da je optimizacija prazne bazne klase u osnovi nemoguća s višestrukim nasljeđivanjem je od Davida Vandevoordea i Nikolaja M. Josutisa (Nickolai M. Josuttis) "Šabloni C ++ (Addison-Wesley, 2003). Moje početno razumijevanje o tome šta je ključna riječ typename u pravilu 42 zasniva se na C ++ i C FAQ ( http://www.comeaucomputing.com/techtalk/#typename), podržan od Grega Comeaua, a Leor Zolman mi je pomogao da shvatim da je ovo gledište pogrešno (moja greška, a ne Gregova). Tema za pravilo 46 potiče iz govora Dana Saksa "Kako steći nove prijatelje". Ideja na kraju Pravila 52 da, ako deklarirate jednu verziju nove, morate deklarirati sve ostale, iznesena je u problemu 22 Izuzetnog C++ Herba Suttera. Moje razumijevanje procesa provjere Boost (sažeto u pravilu 55) je poboljšao David Abrahams.

    Sve navedeno se tiče gdje i od koga sam nešto naučio, bez obzira ko je prvi objavio materijal na relevantnu temu.

    U mojim bilješkama također stoji da sam koristio informacije od Stevea Clamagea, Antoinea Truxa, Timothyja Knoxa i Mikea Kaelblinga, iako nažalost nije precizirano gdje i kako.

    Nacrte prvog izdanja recenzirali Tom Cargill, Glenn Caroll, Tony Davis, Brian Kernigan, Jak Kirman, Doug Lea, Moises Lejter), Eugene Santos Jr. (Eugene Santos, Jr.), John Shewchuk, John Stasko, Bjarne Stroustrup, Barbara Tilly i Nancy L. Urbano. Osim toga, prijedloge za poboljšanja koja su ugrađena u kasnija reizdanja dali su 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 Trucks, Cade Roux, Chandrika Gokul, Randy Mangoba i Glenn Teitelbaum.

    Nacrte drugog izdanja recenzirali: Derek Bosch, Tim Johnson, Brian Kernighan, Junichi Kimura, Scott Lewandowski, Laura Michaels, David Smallberg, Clovis Tonado, Chris Van Wyk i Oleg Zabluda. U kasnijim serijama koristili su komentari Daniela Steinberga, Arunprasada Maratha, Douga Stappa, Roberta Halla, Cheryl Ferguson, Gary Bartlett, Michaela Bartla Tam Michael Tamma, Kendall Beaman, Erica Naglera, Maxa Hailperina, Joea Gottmana, Richarda Weeksa, Valentina Bonnarda, Juna On, Tim King, Don Mailer, Ted Hill, Marc Harrison, Michael Rubinstein, Marc Rodgers, David Goh, Brenton Brenton Cooper, Andy Thomas-Cramer, Anton Trucks, John Walt, Brian Sharon, Liam Fitzpatric, Bernd Mohr, Harry Yee ( Gary Yee), John O "Henley, Brady Paterson, Christopher Peterson (Hrist opher Peterson, Feliks Kluzniak, Isi Dunetz, Christopher Creutzi, Ian Cooper, Carl Harris, Marc Stickel, Clay Budin, Panayotis Matsinopulos, David Smallberg, Herb Sutter, Pajo Mišljenčević, Giulio Agostini, Fredrik Blomqvistrik (Fred Wilnderqvistrense), J. Kuzminski, Kazunobu Kuriyama, Michael Christensen, Jorge Yanez Teruel, Mark Davis, Marty Rabinowitz, Ares Lagae (Ares Lagae) i Alexander Medvedev.

    Rane djelomične nacrte ovog izdanja recenzirali su: Brian Kernighan, Angelica Lunger, Jesse Lachley, Roger P. Pedersen, Chris Van Wyck, Nicholas Stroustrup i Hendrick Schober. Kompletan nacrt pregledali su: Leor Zolman, Mike Tsao, Eric Nagler, Zhenet Gutnik, David Abrahams, Gerhard Kreuser, Drosos Kouronis, Brian Kernigan, Andrew Crims, Balog Pal, Emily Jagdhar, Eugene Kalenkovich, Mike Rose, Benjko Carrarara, Jack Reeves, Steve Shirippa, Martin Fallenstedt, Timothy Knox, Yoon Bai, Michael Lancetta, Philip Janert, Judo Bartholucci, Michael Topic, Jeff Scherpeltz, Chris Naurot, Nishant Mittal, Jeff Sommers, Hrendon Morungoff Lee, Jim Meellerth, Al Geehan, Al Sing, Sam Lee, Sasan Dashinejad, Alex Martin, Steve Cai, Thomas Fruchterman, Corey Hicks, David Smallberg, Gunawardan Kakulapati, Danny Rabbani, Jake Cohen, Hendrik Schuber, Paco Wiziana, Glenn Jeffrey D. Oldham, Nicholas Stroustrup, Matthew Andrei Alexandrescu, Tim Johnson, Leon Matthews, Peter Dulimov i Kevlin Henney. Neke pojedinačne paragrafe su također izradili Herb Sutter i Attila F. Feher.

    Recenzija sirovog (i možda nekompletnog) rukopisa je težak posao, a kratki rokovi ga samo dodatno otežavaju. Zahvalan sam svima koji su izrazili želju da mi pomognu u tome.

    Pregled rukopisa je tim teži ako nemate pojma o materijalu, ali ga ne smijete propustiti nijedan netačnosti koje su se mogle uvući u tekst. Neverovatno je da ima ljudi koji su voljni da uređuju tekstove. Christa Meadowbrook je bila urednica ove knjige i bila je u stanju da identifikuje mnoge greške koje su svi ostali propustili.

    Leor Zolman je provjerio sve primjere koda na različitim kompajlerima tokom pregleda rukopisa, a onda je to učinio ponovo nakon što sam napravio izmjene. Ako neka greška ostane, ja sam odgovoran za njih, a ne Leor.

    Karl Wigers i posebno Tim Johnson napisali su kratak, ali koristan naslovni tekst.

    Džon Vejt, urednik prva dva izdanja ove knjige, nehotice je pristao da ponovo radi u ovom svojstvu. Njegova asistentica, Denise Mikelsen, je uvijek odgovarala ugodnim osmijehom na moje česte i dosadne primjedbe (barem tako mislim, iako je lično nikad nisam sreo). Julia Nahil je "izvukla kratku slamku", morala je biti odgovorna za izradu ove knjige. Šest sedmica je sjedila noću kako bi pratila svoj raspored bez gubljenja prisebnosti. John Fuller (njen šef) i Marty Rabinovich (njen šef) su također bili direktno uključeni u pripremu publikacije. Službene dužnosti Vanesse Moore bile su da postavi knjigu u FrameMaker i kreira PDF tekst, ali se dobrovoljno prijavila da doda Dodatak B i formatira ga za štampanje na unutrašnjoj korici. Solveig Hugland je pomogao sa indeksom. Sandra Schreueder i Chuti Praserzit su bile zadužene za dizajn omota. Čuči je bio taj koji je morao da prepravlja naslovnicu svaki put kada sam rekao: "Kako bi bilo da stavim ovu fotografiju, ali sa prugom druge boje?" Chanda Lehry-Cooty je bila potpuno iscrpljena reklamirajući knjigu.

    Nekoliko mjeseci dok sam radio na rukopisu, televizijska serija Buffy ubica vampira pomogla mi je da se oslobodim stresa na kraju dana. Bilo je potrebno mnogo truda da se Buffyin govor izbaci sa stranica ove knjige.

    Katie Reed me naučila programiranje 1971. i drago mi je da smo ostali prijatelji do danas. Donald French je unajmio Mosesa Lejtera i mene da razvijemo C++ tutorijale 1989. (što me je natjeralo stvarno naučite C++), a 1991. doveo me da ih predstavim na Stratus računaru. Tada su me studenti ohrabrili da napišem ono što će kasnije postati prvo izdanje ove knjige. Don me je takođe upoznao sa Džonom Vajtom, koji je pristao da ga objavi.

    Moja supruga, Nensi L. Urbano, nastavlja da podstiče moje pisanje, čak i nakon sedam objavljenih knjiga, prilagođavajući ih za CD i disertaciju. Ima neverovatno strpljenje. Bez nje nikada ne bih mogao da uradim ono što sam uradio.

    Od početka do kraja, naš pas Persefona je bio moj nesebičan pratilac. Nažalost, učestvovala je u većini projekta dok je već bila u grobnoj urni. Mnogo nam nedostaje.

    Top srodni članci