Elõszó
Minél hamarabb alakítsuk ki a szokásainkat: ugyanazt a dolgot mindig ugyanúgy csináljuk. Alakítsuk ki egyéni kifejezésmódunkat. Szabványosítsunk. Shakespeare és köztünk az egyetlen (!) különbség, hogy õ többféleképpen volt képes kifejezni magát, nem pedig az, hogy több szót ismert. – Alan Perlis (kiemelés tõlünk) A szabályokban az a legjobb, hogy olyan sok van belõlük. – Ismeretlen szerzõ Ezt a könyvet arra szántuk, hogy programozói csapatoknak biztosítson kódolási szabályokat, mégpedig két okból: • A kódolási szabályoknak tükrözniük kell a közösség tapasztalait: Egy kódolási szabálynak kipróbált és bizonyított, a nyelv alapos ismeretére épülõ kifejezésmóddal kell rendelkeznie, és különösképpen a szoftverfejlesztés gazdag és kiterjedt irodalmából kell merítenie, hogy a máskülönben szétszórt szabályokat, irányelveket és megoldásokat egybegyûjtse. • A természet nem tûri a légüres teret: Ha nem állítunk fel tudatosan értelmes szabályokat, valaki más fogja megtenni azt helyettünk, hogy ránk erõltesse a sajátjait. Az így kialakított szabályok általában minden olyan jellemzõvel bírnak, ami nemkívánatos egy kódolási szabály esetében, például megpróbálnak minket a C++ minimalista, C stílusú használatára szorítani. A rossz kódolási szabályok közül sokat olyanok állítanak fel, akik nem értik igazán a nyelvet vagy a szoftverfejlesztés folyamatát, vagy túl sok mindent akarnak szabályozni. Egy rossz kódolási szabály hamar elveszíti hitelességét, így a csalódott programozók a legjobb esetben is figyelmen kívül hagyják annak egyébként érvényes irányelveit, ha a többivel nem értenek egyet. Ez a legjobb eset – a legrosszabb, ha a rossz szabályt megpróbálják betartatni.
xii
C++ kódolási szabályok
Hogyan használjuk ezt a könyvet? Gondolkodjunk. A helyes irányelveket tudatosan, de ne vakon kövessük. Az egyes szabályoknál felsoroltuk a kivételeket, hogy tisztázzuk azokat a kevésbé nyilvánvaló helyzeteket, amikor az adott irányelv nem alkalmazható. Semmilyen szabály – legyen bármilyen jó (és a kötetben felállított szabályok szerintünk azok) – nem szabad, hogy helyettesítse a gondolkodást. Minden fejlesztõcsapat maga felel saját szabályainak kialakításáért, és azért, hogy ez megfontoltan történjen. Ebbe a mi csapatunk is beletartozik. Ha vezetõk vagyunk, vonjuk be a csapat tagjait a szabályok felállításába, ugyanis mindenki szívesebben követ olyan szabályokat, amelyeket a sajátjának érez, mint olyanokat, amelyeket kívülrõl kényszerítettek rájuk. A kötetet arra szántuk, hogy programozói csapatoknak alapot biztosítson a kódolási szabályok kialakításához. Nem a miénk az utolsó szó, hiszen egy csapat mindig kiegészíti majd a javaslatainkat olyan irányelvekkel, amelyek rájuk vagy az adott feladatra érvényesek. Mindazonáltal reméljük, hogy a kötet megtakarít némi fáradságot azzal, hogy dokumentálja a széles körben elfogadott és csaknem minden helyzetben alkalmazható megoldásokat (és a kivételeket), és segít az általunk használt kódolási szabályok minõségének és következetességének növelésében. Olvastassuk el csapatunkkal a könyvet és a hivatkozott egyéb anyagokat, és döntsük el, melyek azok az irányelvek, amelyek a mi esetünkben egyáltalán nem mûködnek (mondjuk mert az adott munka sajátos jellemzõkkel bír), a többi mellett pedig kötelezzük el magunkat. Az életbe léptetett szabályokat már nem szabad megszegni, kivéve ha elõtte az egész csapattal megbeszéltük. Végül, idõrõl idõre közösen vizsgáljuk felül az irányelveket, hogy a gyakorlati tapasztalatokból levont következtetéseket beépíthessük a szabályokba.
A kódolási szabályok és a programozó A helyes kódolási szabályoknak számos haszna van, amelyek egymással is összefüggnek: • Jobb minõségû kód: Ha a fejlesztõket arra biztatjuk, hogy következetesen helyes dolgokat csináljanak, közvetlenül javítjuk a szoftver minõségét és karbantarthatóságát. • Gyorsabb fejlesztés: A fejlesztõknek döntéseik meghozatalánál nem kell mindig újraalkotniuk az irányelveket. • Jobb csapatmunka: A szabályok csökkentik a szükségtelen viták mennyiségét, és egyszerûbbé teszik a csapat tagjainak, hogy elolvassák vagy módosítsák egymás kódjait. • Egységesség a megfelelõ területen: A fejlesztõk a lényeges területeken bontakoztathatják ki kreativitásukat.
Elõszó Stressz hatása alatt és az idõ szorításában mindenki azt teszi, amit megtanult, a bevált módszerekhez folyamodik. A kórházak sürgõsségi osztályán ezért alkalmaznak tapasztalt, képzett személyzetet – még a kellõ tudással felvértezett kezdõk is pánikba esnek. Szoftverfejlesztõként rendszeresen nehezedik ránk nagy nyomás, hogy a holnap programját tegnapra szállítsuk le. A határidõk szorításában azt tesszük, amire kiképeztek bennünket és amit megszoktunk. A hanyag programozók, akik normális esetben mit sem tudnak a helyes szoftvertervezési megoldásokról (vagy csak nem szokták alkalmazni azokat), nyomás alatt még hanyagabb és hibásabb kódot írnak, míg azok, akik megfelelõ szokásokat alakítottak ki, és rendszeresen gyakorolják azokat, nem esnek szét, és képesek gyorsan minõségi kódot készíteni. Az ebben a könyvben bemutatott kódolási szabályok olyan irányelvek, amelyek a magas minõségû C++ kódok írását szolgálják, és a C++ közösség gazdag tapasztalatára és az abból levont, alaposan megszûrt következtetésekre épülnek. Ez a tudásanyag eddig csak részletekben volt hozzáférhetõ, különbözõ könyvek és szájhagyomány útján. A kötet célja, hogy ezt a tudást kellõen megindokolt, összefogott szabálygyûjteménybe rendezze, amit könnyen megérthetünk és követhetünk. Természetesen lehetséges, hogy valaki a legjobb kódolási szabályokat követve is rossz kódot írjon. Ez minden nyelvre vagy programozási megközelítésre igaz. Egy jó szabálygyûjtemény túllép azon, hogy puszta szabályhalmaz legyen; inkább a megfelelõ szokásokat alakítja ki, és fegyelmezettségre tanít. Ezzel a szilárd alappal magasabb szintre léphetünk, de nincs rövidebb út: mielõtt versírásba foghatnánk, meg kell tanulnunk a nyelvtant és a szavakat. Reményeink szerint ehhez nyújtunk segítséget. A könyv egyaránt szól a kezdõ és a profi C++-programozókhoz: Ha még csak tanuljuk a programozást, a szabályok és a mögöttük levõ elvek segíthetnek megérteni, mely stílusokat és kifejezésformákat támogatja a C++ a legtermészetesebben. Minden szabályt tömör magyarázattal láttunk el, és irányelvünk, hogy a megértésére biztassunk, ne a szabály puszta bemagolására. A középhaladó és haladó programozóknak igyekeztünk részletes és pontos hivatkozásokat adni a szabályokhoz, hogy mélyebben utánanézhessenek, miként gyökerezik a szabály a C++ típusrendszerében, nyelvtanában és objektummodelljében. Valószínû, hogy csapat tagjaként, bonyolult rendszeren dolgozunk. A kódolási szabályok követése igazán itt kifizetõdõ, hiszen így a csapat azonos szinten dolgozhat és tekintheti át a kódot.
xiii
xiv
C++ kódolási szabályok
Néhány szó a kötetrõl A könyv megszerkesztésekor az alábbiakat tartottuk szem elõtt. • Röviden mindig jobb: A hosszú szabályokat gyakran figyelmen kívül hagyják, míg a rövideket elolvassák és alkalmazzák. • Minden szabálynak egyértelmûnek kell lennie: A kötetben nem új szabályokat alkottunk, hanem meglevõ, széles körben követett szabványokat írtunk le. Ha egy irányelv nem minden esetben követhetõ, ezt a szövegben megfelelõen jeleztük, és a közismert kivételekrõl sem feledkeztünk meg. • Minden szabálynak hiteles szakmai forrásból kell származnia: Az irányelveket hozzáférhetõ szakmai anyagokra való hivatkozásokkal láttuk el, így a kötet C++-irodalomjegyzékként is hasznosítható. • Minden szabályt okkal kell leírni: Olyasmire nem fogalmaztunk meg irányelveket, amit a programozó egyébként is megtenne, amit máshol már tárgyaltunk, vagy amit a fordítóprogram is észrevesz. Példa: A „Ne adjunk vissza mutatót vagy hivatkozást automatikus változóra” jó irányelv, de a könyvben nem szerepel, mert az általunk kipróbált valamennyi fordító figyelmeztet rá, így az 1. szabály hatálya alá tartozik, ami kimondja, hogy „Fordítsunk tisztán és magas figyelmeztetési szinten”. Példa: A „Használjunk szerkesztõprogramot (fordítót, hibakeresõt)” irányelvvel sincs baj, de az említett eszközöket amúgy is használjuk, külön nem kell biztatni rá. Ehelyett már az elején adunk két olyan szabályt, mint a „Használjunk automatizált építõrendszert” és a „Használjunk változatkövetõ rendszert”. Példa: „Ne használjuk a goto-t, csak ha muszáj”: ez egy megszívlelendõ szabály, de tapasztalatunk az, hogy minden programozó ismeri, ezért nem kívántuk mi is elismételni. Minden szabályt a következõképpen építettünk fel: • A szabály „neve”: Ezt egyfajta emlékeztetõnek szántuk, és igyekeztünk a lehetõ legrövidebb formát megtalálni, amirõl a szabály az eszünkbe juthat. • Összefoglalás: A legfontosabb irányelvek röviden. • Kifejtés: A szabály bõvebb kifejtése, amely esetleg tartalmazhat rövidebb hivatkozásokat, de ezek többségét a Hivatkozások részre hagytuk. • Példák (ha vannak): A szabályt illusztráló vagy az emlékezetbe vésést megkönnyítõ példák. • Kivételek (ha vannak): Bármilyen olyan (általában ritka) eset, amikor a szabály nem alkalmazható. Ne essünk abba a gyakori hibába, hogy azt gondoljuk, a mi esetünk biztosan különleges, és így a szabály nem vonatkozik ránk – ez általában hamis képzet. • Hivatkozások: A C++ irodalmából az itt hivatkozott mûveket érdemes áttanulmányozni mélyebb elemzés céljából.
Elõszó A könyv egyes részeiben kineveztünk egy-egy „fõ szabályt”, ami általában az adott rész elsõ szabálya (a szabályokat igyekeztünk fontossági sorrendben bemutatni,) de néha elõfordul, hogy a fõ szabályt nem legelöl találjuk, mert a logika, az olvashatóság, és az, hogy különösen felhívhassuk rá a figyelmet, ezt kívánta meg.
Köszönetnyilvánítás Köszönet illeti a sorozat szerkesztõjét, Bjarne Stroustrupot, valamint Peter Gordon és Debbie Lafferty szerkesztõket, Tyrrell Albaugh-t, Kim Boedigheimert, John Fullert, Bernard Gaffney-t, Curt Johnsont, Chanda Leary-Coutut, Charles Leddy-t, Heather Mullane-t, Chuti Prasertsith-et, Lara Wysongot, illetve az Addison-Wesley kiadó többi munkatársát. Öröm volt velük dolgozni. A „szabálynevekhez” többen is inspirációt adtak, például [Cline99] játékos stílusa, [Peters99] klasszikus import this-e, valamint a legendás (és idézhetõ) Alan Perlis. Külön szeretnénk megköszönni mindazok segítségét, akiknek visszajelzései révén a könyv jobb lett, mint amilyen egyébként lett volna. Közöttük is jelentõs Bjarne Stroustrup hozzájárulása, aki a tervezéstõl a végsõ szövegváltozatig követte és értékelte a mûvünket. Külön köszönet jár Dava Abrahamsnek, Marshall Cline-nak, Kevlin Henney-nek, Howard Hinnantnek, Jim Hyslopnak, Nicolai Josuttisnak, Jon Kalbnek, Max Khesinnek, Stan Lippmannek, Scott Meyersnek és Daveed Vandevoordének, akik aktívan részt vettek az egyes vázlatok részletes értékelésében. Hasznos megjegyzések érkeztek még a következõktõl: Chuck Allison, Samir Bajaj, Marc Barbour, Damian Dechev, Steve Dewhurst, Peter Dimov, Alan Griffiths, Michi Henning, James Kanze, Matt Marcus, Petru Marginean, Robert C. „Uncle Bob” Martin, Jeff Peil, Peter Pirkelbauer, Vladimir Prus, Dan Saks, Luke Wagner, Matthew Wilson és Leor Zolman. Természetesen minden esetleges hibáért minket terhel a felelõsség, nem õket. Herb Sutter Andrei Alexandrescu Seattle, 2004. szeptember
xv