6
Abeceda pisanja C++ klasa Konstruktori, destruktori i operatori dodeljivanja Kada budete razvijali sopstvene klase postavljaćete 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 greške koje čine njihov kôd 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 naučite neke od ovih „caka”. Ovde će biti date neke korisne smernice preuzete od mnogih eksperata za C++ jezik. Počećemo sa funkcijama koje su specijalni članovi klase: konstruktori, destruktori i operatori dodeljivanja. Funkcije specijalni članovi klase Klase sadrže i funkcije i podatke kao članove. Većina funkcija obezbeđuje interfejs ka objektu da omogući korisnicima da primene operacije na klasu. Druge funkcije imaju specijalno značenje, pošto 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 slučajevima, kompajler može da generiše kôd koji kreira objekte za sopstvene potrebe. Objektima se dodeljuje ime (naziv) prilikom deklarisanja. Imenovani objekti mogu se koristiti samo u oblastima važenja (engl. scopes ; opseg vidljivosti) u kojima su definisani. Objekti se mogu koristiti samo unutar oblasti u kojima su definisani. Postoje tri vrste oblasti važenja: lokalna oblast (engl. local scope), koja obuhvata objekte definisane u blokovima koda; oblast fajla (file scope), koja

Konstruktori, Destruktori i Operatori Dodeljivanja

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