Upload
jelena-gavanski
View
26
Download
6
Embed Size (px)
DESCRIPTION
Konstruktori, Destruktori i Operatori Dodeljivanja
Citation preview
Abeceda pisanja C++ klasa
Konstruktori, destruktori i operatori dodeljivanja
Kada budete razvijali sopstvene klase postavljaete sebi mnoga pitanja. Da li
mi je potrebna kopija konstruktora? Da li mi je neophodan podrazumevani
argument u mojim konstruktorima? Kako da obezbedim konverziju tipa za
moju klasu? Da li mi je potreban operator jednakosti? Kako da implementiram
postfiksni operator? Treba li da vratim referencu ili objekat? Kako da ... ?
ak i iskusni C++ programeri postavljaju sebi ta pitanja i opet prave greke
koje ine njihov kd neefikasnim. Postoji obilje literature u kojoj se razmatraju
ti problemi i nude preporuke za implementiranje C++ klasa. Da biste postali
to bolji C++ programer potrebno je da nauite neke od ovih caka.
Ovde e biti date neke korisne smernice preuzete od mnogih eksperata za
C++ jezik. Poeemo sa funkcijama koje su specijalni lanovi klase:
konstruktori, destruktori i operatori dodeljivanja.
Funkcije specijalni lanovi klase
Klase sadre i funkcije i podatke kao lanove. Veina funkcija obezbeuje
interfejs ka objektu da omogui korisnicima da primene operacije na klasu.
Druge funkcije imaju specijalno znaenje, poto one imaju specijalnu ulogu
tokom ivotnog veka objekta. Funkcije specijalni lanovi klase su konstruktori,
destruktor i operator dodeljivanja.
ivotni vek objekta
Objekti se uvode u program preko deklaracija. U nekim sluajevima, kompajler
moe da generie kd koji kreira objekte za sopstvene potrebe. Objektima se
dodeljuje ime (naziv) prilikom deklarisanja. Imenovani objekti mogu se
koristiti samo u oblastima vaenja (engl. scopes ; opseg vidljivosti) u kojima
su definisani. Objekti se mogu koristiti samo unutar oblasti u kojima su
definisani.
Postoje tri vrste oblasti vaenja: lokalna oblast (engl. local scope), koja
obuhvata objekte definisane u blokovima koda; oblast fajla (file scope), koja
obuhvata objekte u fajlu, ali izvan svih blokova i klasa; i oblast klase (class
scope), koja obuhvata objekte deklarisane kao podatke lanove klase. Objekti
oblasti fajla smatra se da su globalni.
ivotni vek nekog objekta odreen je njegovom klasom memorisanja (storage
class):
Automatski. Objekti deklarisani unutar bloka smatra se da su automatski. Automatski objekti se kreiraju i inicijalizuju svaki put kada
kontrola toka program dostigne svoju definiciju a unitavaju po izlasku iz
bloka.
Statiki. Objekti sa prefiksom static su statiki i postoje i zadravaju svoje vrednosti u toku celog izvravanja programa. Globalni objekti su
takoe statini. Statini objekti se kreiraju i inicijalizuju pre prvog
korienja bilo koje funkcije u konkretnoj translacionoj jedinici.
Podrazumeva se da se statiki objekti automatski inicijalizuju na nulu.
C++ obezbeuje mehanizme za osiguravanje da se vai objekti odgovarajue
inicijalizuju pre nego to se koriste. Kako vai objekti ulaze i izlaze iz oblasti
vaenja, memorija se alocira/dealocira (rezervie/oslobaa) za njih a zatim se
ta memorija inicijalizuje. C++ obezbeuje specijalnu funkciju lanicu za
inicijalizaciju objekta koja se naziva konstruktor.
Konstruktor se poziva kadgod se neki objekat kreira. Objekti se mogu kreirati:
kao globalne promenljive, kao lokalne promenljive, preko eksplicitnog
korienja operatora new, preko eksplicitnog poziva konstruktora ili kao
privremeni objekat. Konstruktori se takoe pozivaju kada se neki objekat
kreira kao deo drugog objekta.
Slino, kada va objekat izae iz oblasti vaenja, memorija koju je koristio taj
objekat mora se oistiti. C++ obezbeuje specijalnu funkciju lanicu , tzv.
destruktor, koja se poziva kadgod se va objekat unitava tako da moete da
obavite bilo koji proces ienja, kao to je oslobaanje memorije ili drugih
sistemskih resursa koje je koristio objekat.
C++ takoe obezbeuje jo dve specijalne funkcije koje imaju specijalnu
ulogu. Kadgod neki objekat mora da se kopira, uvodi se njegov konstruktor za
kopiranje (engl. copy constructor). Konano, kadgod se nekom objektu
dodeljuje vrednost, uvodi se njegov operator dodeljivanja.
Konstruktori
Konstruktor je odgovoran za pretvaranje sirove memorije alocirane nekom
objektu u upotrebljiv objekat. Konstruktori se javljaju u vie oblika. Postoje
podrazumevani konstruktori, konstruktor za kopiranje i drugi konstruktori koji
prihvataju razliite argumente.
Podrazumevani konstruktor
Podrazumevani konstruktor je konstruktor koji nema argumenata.
Podrazumevani konstruktor za klasu X ima oblik X::X(). Konstruktor koji ima
sve podrazumevane argumente, X::X(const int x=0), na primer, takoe je
podrazumevani konstruktor, poto se on moe pozvati bez argumenata.
Podrazumevani konstruktori omoguavaju objektima da budu kreirani bez
prosleivanja bilo kakvih parametara konstruktoru. Na primer, deklaracija
String s;
Za rezultat daje string s koji jo uvek nema vrednost; to je jedan prazan
string.
Podrazumevani konstruktor obino kreira objekat koji predstavlja null instancu
konkretnog tipa koji klasa oznaava. Podrazumevani konstruktor za
kompleksni broj moe rezultirati u objektu sa vrednou nula, dok
podrazumevani konstruktor za povezanu listu moe rezultirati praznom listom.
Preporuka 1. Obezbedite podrazumevani konstruktor za svoju klasu. Koristite
podrazumevane argumente da izbegnete pojavljivanje posebnog
podrazumevanog konstruktora koji nema argumente.
esto ete omoguiti korisnicima vaih klasa da prosleuju argumente
konstruktoru. Bolje je da obezbedite konstruktora sa podrazumevanim
argumentima koji moe da slui kao podrazumevani konstruktor ili kao
konstruktor koji prihvata argumente koje specificira nego da obezbedite
poseban podrazumevani konstruktor koji ne prihvata (nema) argumente.
Na primer, dva konstruktora String, String() i String(const char* str), mogu da
se kombinuju u jedan konstruktor koji ima podrazumevani argument:
String(const char* str=0).
Moe da postoji samo jedan podrazumevani konstruktor, zato nemojte
dodavati podrazumevane argumente svim argumentima svakog konstruktora
va kompajler e se verovatno aliti.
Kada definiete svoje klase moe se desiti da ne moete da imate
podrazumevani konstruktor zato to je potrebno da odreeni podaci lanovi
budu inicijalizovani prilikom kreiranja. Meutim, ako obezbedite nain kojim se
osigurava da e ovi podaci lanovi kasnije biti obezbeeni tada jo uvek
moete imati podrazumevani konstruktor. Na primer, ako koristite C++
iostream biblioteku, znate da moete da deklariete izlazni fajl bez navoenja
imena fajla:
ofstream out;
Ime fajla se kasnije obezbeuje prilikom pozivanja otvaranja:
out.open("outfile");
Budite paljivi kod implementiranja ablona. Ponekad ako ne vodite dovoljno
rauna kako implementirate kd, moe se desiti da primorate svoje korisnike
da koriste svoje tipove koji imaju podrazumevani konstruktor. Ako stavite
T element;
U neku od svojih ablon funkcija, primoravate svoje korisnike da koriste tipove
koji imaju podrazumevani konstruktor.
Preporuka 2. Koristitese podrazumevane argumente u svim funkcijama
lanicama gde je to prikladno.
Podrazumevani argumenti nisu ogranieni na konstruktore, njih moe da
koristi bilo koja funkcija lanica. Obezbedite odgovarajue podrazmevane
vrednosti kadgod je to prikladno.
Konstruktor za kopiranje
Konstruktor za kopiranje je specijalni konstruktor koji moe da se pozove da
kopira objekat. Konstruktor za kopiranje za klasu X ima oblik X::X(const X&). U sledeem fragmentu koda s2 se kreira pozivanjem String-ovog konstruktora za kopiranje da kopira s1:
String s1("Hello, world!"); String s2 (s1);
Konstruktor za kopiranje se esto poziva iza scene kadgod kompajler treba da
kopira neki objekat. Ovi objekti, prikladno se nazivaju temporaries, kreiraju se
i unitavaju kada je to potrebno kompajleru. Najee se to deava tokom
pozivanja funkcija kako bi mogla da se zadri semantika poziva po vrednosti
(call-by-value). Na primer, data je funkcija koja prihvata String argument:
void DisplayError (const String s);
Kadgod se DisplayError() pozove, kompajler generie poziv za konstruktor za
kopiranje za String da kreira temporary za parametar s. temporary se zatim
prosleuje funkciji.
Preporuka 3. Uvek obezbedite konstruktor za kopiranje za svoje klase.
Nemojte preputati kompajleru da ga generie umesto vas. Ako vaa klasa ima
pointerske lanove podatke, morate obezbediti konstruktor za kopiranje.
Ako ne obezbedite konstruktor za kopiranje, kompajler e ga automatski
generisati umesto vas. Taj generisani konstruktor za kopiranje jednostavno
obavlja dodeljivanje za sve podatke lanove klase. To je zgodno kod klase koja
ne sadri bilo kakve pointerske promenljive. (Parametar konstruktora za
kopiranje je referenca na objekat iste klase.) Korisno je da vam postane
navika da uvek obezbeujete konstruktor za kopiranje za svoje klase.
Pripremio Dragan Markovi
Abeceda pisanja C++ klasaFunkcije specijalni lanovi klase