konstruktor destruktor

24
Programski jezici 1 1. dio mr Dražen Brđanin Elektrotehnički fakultet Banja Luka 2009 KLASE I APSTRAKCIJA PODATAKA

Upload: mitar-demkovic

Post on 28-Dec-2015

68 views

Category:

Documents


6 download

DESCRIPTION

Konstruktori i destruktori u programiranju.

TRANSCRIPT

Page 1: Konstruktor Destruktor

Programski jezici 1

1. dio

mr Dražen Brđanin

Elektrotehnički fakultetBanja Luka

2009

KLASE I APSTRAKCIJA PODATAKA

Page 2: Konstruktor Destruktor

Klase – 1. dio

Sadržaj Razlike C/C++ programiranja Osnovne karakteristike klase Definisanje klase Specifikatori pristupa članovima klase Razlike između definicije i deklaracije klase Oblast definisanosti i pristup članovima klase Pomoćne funkcije u klasi Modularizacija Inicijalizacija objekata – konstruktori Destruktori Redoslijed izvršavanja konstruktora i destruktora

Page 3: Konstruktor Destruktor

Osnovne razlike C i C++ programiranja

Programiranje u jeziku C Proceduralno (algoritamski)

orijentisano

Jedinica programiranja – FUNKCIJA

Programeri se koncentrišu na pisanje funkcija, funkcije se grupišu u program

Podaci nisu primarni, oni su u funkciji podrške akcijama koje funkcije izvode

Glagoli određuju šta sistem radi i koje će funkcije biti implementirane

Instance ugrađenih tipova (int, char, …) nazivaju se promjenljive (varijable)

Programiranje u jeziku C++

Objektno orijentisano

Jedinica programiranja – KLASA

Programeri se koncentrišu na kreiranje vlastitih tipova podataka – KLASE

Imenice su te koje određuju sistem (imenice određuju klase)

Svaka klasa sadrži podatke i funkcije za manipulaciju podacima

Podaci koji se nalaze u klasi nazivaju se podaci članice (data members)

Funkcije koje se nalaze u klasi nazivaju se funkcije članice (metode)

Instance korisnički definisanih tipova (klasa) nazivaju se objekti

Page 4: Konstruktor Destruktor

Osnovne karakteristike klase

KLASA omogućava modelovanje objekata, koje karakterišu: atributi (podaci članice – data members)

ponašanje ili operacije (funkcije članice – member functions)

U nekim OO programskim jezicima funkcije članice se nazivaju

metode.

Najvažnije karakteristike KLASE kao pravog tipa podataka: Određuju moguće vrijednosti objekata,

Određuju moguće operacije nad objektima,

Obezbjeđuju obaveznu inicijalizaciju objekata pri njihovom stvaranju,

Obezbjeđuju uništavanje objekata kada više nisu potrebni,

Obezbjeđuju enkapsulaciju atributa i ponašanja u jedinstevnu cjelinu,

Omogućavaju princip skrivanja informacija (information hiding).

Page 5: Konstruktor Destruktor

Definisanje klase

KLASA se definiše korišćenjem ključne

riječi class.

Uobičajeno naziv klase započinje velikim slovom.

Opšti oblik definicije klase

class Ime

{

tip clan;

public:

tip clan;

private:

tip clan;

};

javni članovi klase

privatni članovi klase

privatni članovi klase

Page 6: Konstruktor Destruktor

privatni članovi klase

javni članovi klase

Primjer definicije klase

class Razlomak

{

public:

Razlomak();void

setBrojilac(int b);void

setImenilac(int n);void

printRazlomak();float vrijednost();

private:

int brojilac;int imenilac;

};

Funkcije članice najčešće su javni

članovi klase

Podaci članice najčešće su privatni

članovi klase (skrivanje

informacija)

Page 7: Konstruktor Destruktor

Specifikatori pristupa članicama klase

public Sve članice definisane iza

specifikatora public: su javne.

Javna članica klase dostupna je iz bilo kojeg dijela programa u kojem je dostupan objekat date klase.

Javna članica dostupna je i iz unutrašnjosti klase.

Uobičajeno su funkcije članice javne članice klase (funkcije opisuju ponašanje, odnosno operacije nad objektima).

private Sve članice definisane iza

specifikatora private: su privatne.

Privatnoj članici klase ne može se pristupiti spolja, već samo iz unutrašnjosti klase.

Privatnoj članici klase pristupa se posredstvom funkcija članica te klase.

Privatnoj članici klase mogu da pristupe i tzv. prijatelji klase, tj. prijateljske funkcije klase.

Uobičajeno su podaci članice privatni članovi klase (princip skrivanja informacija).

Postoje i protected (zaštićeni) članovi klase – primjenjuje se

kod nasljeđivanja.

Specifikatori pristupa:

• mogu da mijenjaju mjesta,

• mogu više puta da se navode,

• ako se izostavi, podrazumijeva se private.

Page 8: Konstruktor Destruktor

Definicija klase <-> Deklaracija klase

Definicija klase podrazumijeva navođenje svih članica klase.

Deklaracija klase podrazumijeva da se samo naznači (deklariše) da neki identifikator predstavlja klasu.

Opšti oblik deklaracije klase:

class Ime;

Kad je klasa definisana, mogu se definisati (kreirati) i njene instance (objekat, niz objekata, upućivač, pokazivač na objekat).

Primjer:

Klasa objekat;Klasa objekat;

Klasa nizKlasa niz[100];[100];

Klasa *pointer;Klasa *pointer;

Klasa &upucivac = Klasa &upucivac = objekat;objekat;

Ako je poznata samo deklaracije klase ne mogu se instancirati objekti, već mogu samo da se definišu pokazivači.

Page 9: Konstruktor Destruktor

Definicija funkcija članica klase

Funkcije članice mogu da se definišu unutar klase.

Funkcije članice mogu da se definišu izvan klase, ali se unutar klase treba navesti njihov prototip. Primjer:

class class CounterCounter {{ private:private:

int count;int count; public:public:

......void printvoid print() ()

{ { cout << cout << countcount;;

}}......

};};

Primjer:

class class CounterCounter {{

private:private:int count;int count;

public:public:......void printvoid print()();; ......

};};

void void CounterCounter::print()::print()

{ { cout << cout << countcount;; }}

Praksa pokazuje da je bolje unutar klase navesti samo prototip, a funkciju članicu definisati izvan

funkcije.

Page 10: Konstruktor Destruktor

Oblast definisanosti i pristup članovima

Članice klase dostupne su svim ostalim članicama date klase. Referenciraju se navođenjem imena članice.

Izvan klase, članice klase mogu da se referenciraju pomoću: objekta - objekat.clanica pokazivača na objekat - pokazivac->clanica ili

(*pokazivac).clanica upućivača na objekat - upucivac.clanica

Promjenljive definisane u nekoj funkciji članici vidljive su samo u toj funkciji.

Ako je unutar funkcije članice definisana promjenljiva sa istim imenom kao neki podatak član klase, onda lokalna promjenljiva maskira podatak član.

Pristup maskiranom atributu preko operatora za razrješavanje dosega (::).

Page 11: Konstruktor Destruktor

Oblast definisanosti i pristup članovima

Primjer:

#include <iostream.h>#include <iostream.h>

class Counterclass Counter{{ public:public: int x;int x; void print() { cout << x << endl; }void print() { cout << x << endl; }};};

main()main(){{ Counter c; Counter c; // kreira objekat c (instanca klase Counter)// kreira objekat c (instanca klase Counter) Counter *pc = &c; Counter *pc = &c; // pointer na c// pointer na c Counter &uc = c; Counter &uc = c; // upucivac na c// upucivac na c

c.x = 7; c.x = 7; // postavlja vrijednost atributa objekta// postavlja vrijednost atributa objekta c.print(); c.print(); // direktan poziv funkcije članice// direktan poziv funkcije članice

uc.x = 8; uc.x = 8; // postavlja vrijednost pomocu upucivaca// postavlja vrijednost pomocu upucivaca uc.print(); uc.print(); // poziv funkcije pomocu upucivaca// poziv funkcije pomocu upucivaca

pc->x = 10; pc->x = 10; // postavlja vrijednost pomocu pointera// postavlja vrijednost pomocu pointera pc->print(); pc->print(); // poziv funkcije pomocu pointera// poziv funkcije pomocu pointera}}

7810

Podatak član x je javni atribut. Ovo treba izbjegavati!

Ovdje je korišćeno samo radi ilustracije pristupa!

Page 12: Konstruktor Destruktor

Oblast definisanosti i pristup članovima

Primjer:

#include <iostream.h>#include <iostream.h>int x; // globalna promjenljivaint x; // globalna promjenljivaclass Klasaclass Klasa{{ public:public: void set(int i) { x=i; }void set(int i) { x=i; } void primjer();void primjer(); private:private: int x; // podatak clanint x; // podatak clan};};void Klasa::primjer()void Klasa::primjer(){{ int x=1; // lokalna promjenljivaint x=1; // lokalna promjenljiva cout << "Lokalno x: " << x << endl;cout << "Lokalno x: " << x << endl; cout << "Atribut x: " << Klasa::x << endl;cout << "Atribut x: " << Klasa::x << endl; cout << "Globalno x: " << ::x;cout << "Globalno x: " << ::x;}}main()main(){{ Klasa t;Klasa t; t.set(100);t.set(100); t.primjer();t.primjer();}}

Lokalno x: 1Atribut x: 100Globalno x: 0

Page 13: Konstruktor Destruktor

Oblast definisanosti i pristup članovima

Primjer:

#include <iostream.h>#include <iostream.h>

class Timeclass Time{{ public:public: void setTime(int, int, int);void setTime(int, int, int); void printM();void printM(); void printS();void printS(); private:private: int sat, min, sek;int sat, min, sek;};};

void Time::setTime(int h, int m, int s)void Time::setTime(int h, int m, int s){{ sat = ( h >= 0 && h < 24 ) ? h : 0;sat = ( h >= 0 && h < 24 ) ? h : 0; min = ( m >= 0 && m < 60 ) ? m : 0;min = ( m >= 0 && m < 60 ) ? m : 0; sek = ( s >= 0 && s < 60 ) ? s : 0;sek = ( s >= 0 && s < 60 ) ? s : 0;}}

void Time::printM()void Time::printM(){{ cout << (sat<10?"0":"") << sat << ":";cout << (sat<10?"0":"") << sat << ":"; cout << (min<10?"0":"") << min;cout << (min<10?"0":"") << min;}}

void Time::printS()void Time::printS(){{ cout << ((sat==12)?12:sat%12 ) << ":";cout << ((sat==12)?12:sat%12 ) << ":"; cout << (min<10 ? "0":"") << min << ":";cout << (min<10 ? "0":"") << min << ":"; cout << (sek<10 ? "0":"") << sek;cout << (sek<10 ? "0":"") << sek; cout << (sat<12 ? “AM" : “PM" );cout << (sat<12 ? “AM" : “PM" );}}

main()main(){{ Time t;Time t; t.setTime(13t.setTime(13,,27,6);27,6); cout << "cout << "VrijemeVrijeme : "; : "; t.printM(); cout<<" ili "; t.printS();t.printM(); cout<<" ili "; t.printS(); t.setTimet.setTime((99,99,99);99,99,99); cout << "\nPokusaj : ";cout << "\nPokusaj : "; t.printM(); cout<<" ili "; t.printS();t.printM(); cout<<" ili "; t.printS();}}

Vrijeme : 13:27 ili 1:27:06 PMPokusaj : 00:00 ili 0:00:00 AM

Page 14: Konstruktor Destruktor

Oblast definisanosti i pristup članovima

Privatnim članovima klase mogu da pristupe: funkcije članice date klase “prijateljske” funkcije date klase.

Tipično se implementiraju sljedeće funkcije članice: za postavljanje atributa - tzv. set

funkcijanpr. setTime, setMin, setSek

za očitavanje atributa - tzv. get funkcija npr. getSat, getMin, getSek

Primjer:

class Bankaclass Banka {{ private:private: floatfloat stanjestanje;; public:public: ...... void setStanjevoid setStanje((float nsfloat ns)) { stanje = ns; }{ stanje = ns; }

float getStanje()float getStanje() { return stanje; }{ return stanje; } ...... };}; ...... Banka racun;Banka racun; racun.setStanje(0);racun.setStanje(0); cout << racun.getStanje(); cout << racun.getStanje();

Page 15: Konstruktor Destruktor

Pomoćne funkcije u klasi

Ne moraju sve funkcije članice da budu javne (pogotovo ako one nisu dio interfejsa klase).

Ako neka funkcija služi kao pomoćna funkcija (helper ili utility function) u klasi, tako da npr. nešto računa ili slično za neku drugu funkciju članicu klase, tada takvu pomoćnu funkciju ostavljamo kao privatnu.

Funkcije članice koje čine interfejs klase, odnosno omogućavaju pristup privatnim članovima klase nazivamo i pristupne funkcije (access functions).

Funkcije članice koje provjeravaju ispunjenost nekog uslova (npr. da li je podatak ovakav ili onakav, da li je štampač spreman, da li je lift zauzet i sl.) nazivaju se predikatske funkcije (predicate functions).

Page 16: Konstruktor Destruktor

Modularizacija

U realizaciji većih programa preporučljivo je modularizovati kod. Pri tome interfejs klase treba odvojiti od implementacije.

primjer.h (interfejs)

#ifndef PRIMJER#ifndef PRIMJER#define PRIMJER#define PRIMJER

class Timeclass Time{{ public:public: void setTime(int, int, int);void setTime(int, int, int); void printM();void printM(); void printS();void printS(); private:private: int sat, min, sek;int sat, min, sek;};};

#endif#endif

primjer.cpp (implementacija)

#include <iostream.h>#include <iostream.h>#include "primjer.h"#include "primjer.h"

void Time::setTime(int h, int m, int s)void Time::setTime(int h, int m, int s){{ sat = ( h >= 0 && h < 24 ) ? h : 0;sat = ( h >= 0 && h < 24 ) ? h : 0; min = ( m >= 0 && m < 60 ) ? m : 0;min = ( m >= 0 && m < 60 ) ? m : 0; sek = ( s >= 0 && s < 60 ) ? s : 0;sek = ( s >= 0 && s < 60 ) ? s : 0;}}

void Time::printM()void Time::printM(){{ cout << (sat<10?"0":"") << sat << ":";cout << (sat<10?"0":"") << sat << ":"; cout << (min<10?"0":"") << min;cout << (min<10?"0":"") << min;}}

void Time::printS()void Time::printS(){{ cout << ((sat==12)?12:sat%12 ) << ":";cout << ((sat==12)?12:sat%12 ) << ":"; cout << (min<10 ? "0":"") << min << ":";cout << (min<10 ? "0":"") << min << ":"; cout << (sek<10 ? "0":"") << sek;cout << (sek<10 ? "0":"") << sek; cout << (sat<12 ? “AM" : “PM" );cout << (sat<12 ? “AM" : “PM" );}}

projekat.cpp (glavni program)

#include <iostream.h>#include <iostream.h>#include "primjer.h"#include "primjer.h"

main()main(){{ Time t; ...Time t; ...}}

Page 17: Konstruktor Destruktor

Inicijalizacija objekata - KONSTRUKTORI

Konstruktor – specijalna funkcija članica koja omogućava inicijalizaciju objekta prilikom njegovog kreiranja.

Konstruktor ima isto ime kao i klasa kojoj pripada. Konstruktor nema tip – čak ni void! Konstruktor se automatski poziva svaki put kad se kreira neki objekat.

Primjer:

class Timeclass Time

{{

private:private:

int hh, mm, ss;int hh, mm, ss;

public:public:

......

Time() { hh = mm = ss = 0; }Time() { hh = mm = ss = 0; }

......

};};

......

Time Time tt;;

Page 18: Konstruktor Destruktor

Inicijalizacija objekata - KONSTRUKTORI

Iako programer eksplicitno ne poziva konstruktor pri kreiranju objekta, ipak je moguće u konstruktor prenijeti parametre kojima će se inicijalizovati atributi. Ovi parametri nazivaju se inicijalizatori i navode se unutar malih zagrada prilikom definisanja objekta. Inicijalizatori predstavljaju argumente koji se prosljeđuju konstruktoru.

Primjer:

class Timeclass Time {{ private:private: int hh, mm, ss;int hh, mm, ss;

public:public: Time(int h, int m, int s) Time(int h, int m, int s) { {

hh=h; mm=m; ss=s; hh=h; mm=m; ss=s; }}

};};

… …

Time podne(12,0,0), ponoc(0,0,0); Time podne(12,0,0), ponoc(0,0,0);

Klasa ne mora da ima konstruktor. Objekti mogu da se inicijalizuju drugim

funkcijama članicama. Praksa pokazuje da je najbolje da

se objekat inicijalizuje konstruktorom.

Page 19: Konstruktor Destruktor

Inicijalizacija objekata - KONSTRUKTORI

Konstruktori mogu da se preklapaju – više konstruktora sa preklopljenim imenom u klasi, što omogućava različite načine inicijalizacije objekata (različita početna stanja).

Primjer:

class Timeclass Time{{ private:private: int hh, mm, ss;int hh, mm, ss; public:public: Time(int h, int m, int s) Time(int h, int m, int s)

{ hh=h; mm=m; ss=s; }{ hh=h; mm=m; ss=s; } Time(int s) Time(int s)

{ hh=s/3600; mm=(s%3600)/60; ss=s%60; }{ hh=s/3600; mm=(s%3600)/60; ss=s%60; }};};

......

Time podne(12,0,0);Time podne(12,0,0);

Time Time petdo12(11,55petdo12(11,55,0,0));;

Time ponoc(0);Time ponoc(0);

Page 20: Konstruktor Destruktor

Inicijalizacija objekata - KONSTRUKTORI

Konstruktor može da ima i podrazumijevane vrijednosti argumenata.

Primjer:

class Timeclass Time{{ private:private: int hh, mm, ss;int hh, mm, ss; public:public: Time(int hTime(int h=0=0, int m, int m=0=0, int s, int s=0=0) ) { { hh=h; mm=m; ss=s; hh=h; mm=m; ss=s; }}};};

……

Time podne(12), ponocTime podne(12), ponoc, petdo12(11,55), petdo12(11,55); ;

Page 21: Konstruktor Destruktor

Inicijalizacija objekata - KONSTRUKTORI

Podrazumijevane vrijednosti mogu da se navedu u prototipu konstruktora – tada se ne navode u definiciji konstruktora!

Podrazumijevane vrijednosti mogu da se navedu u definiciji konstruktora – tada se ne navode u prototipu konstruktora!

Primjer:

class Timeclass Time {{ private:private: iint nt hh, mm, sshh, mm, ss;; public:public: ...... Time(int=0, int=0, int=0);Time(int=0, int=0, int=0); ...... };}; ...... Time::Time(int h, int m, int s)Time::Time(int h, int m, int s) {{ hh=h; mm=m; ss=s;hh=h; mm=m; ss=s; }}

Primjer:

class Timeclass Time {{ private:private: iint nt hh, mm, sshh, mm, ss;; public:public: ...... Time(int, int, int);Time(int, int, int); ......};};......Time::Time(int hTime::Time(int h=0=0, int m, int m=0=0, int s, int s=0=0)){{ hh=h; mm=m; ss=s;hh=h; mm=m; ss=s;}}

Nije dozvoljeno podrazumijevane vrijednosti navoditi i u prototipu i u definiciji konstruktora (isto važi i za ostale funkcije članice!)!

Page 22: Konstruktor Destruktor

DESTRUKTORI

Destruktori – slično konstruktoru – još jedna specijalna funkcija članica klase

Destruktor se poziva svaki put kad se uništava neki objekat.

Destruktor suštinski ne uništava objekat (objekat će biti uništen i u slučaju da klasa nema definisan destruktor) - destruktor služi za “čišćenje memorije” (bitno kod objekata koji dinamički alociraju memoriju).

Klasa može da ima samo jedan destruktor. Nije dozvoljeno preklapanje imena.

Destruktor nema argumenata! Destruktor nema tip!

Destruktor ima isto ime kao konstruktor, ali se ispred stavlja tilda (~). Intuitivno se može napraviti analogija sa bitskim operatorom negacije, jer se destruktor ponaša kao komplement konstruktora.

class Timeclass Time {{

public:public: ...... ~Time()~Time();; ......

};};

Page 23: Konstruktor Destruktor

Redoslijed konstruktora i destruktora

Konstruktori i destruktori se pozivaju automatski.

Redoslijed kojim se pozivaju ove funkcije zavisi od redoslijeda kojim se ulazi i izlazi iz domena u kojem se objekti kreiraju. Generalno, destruktori se pozivaju obrnutim redoslijedom u odnosu na poziv konstruktora.

Za globalne objekte: Konstruktor se poziva prije bilo koje funkcije (i prije main funkcije) – tj.

prije početka izvršavanja programa. (u slučaju više fajlova, redoslijed izvršavanja konstruktora nije unaprijed poznat!)

Destruktor se poziva nakon završetka izvršavanja main().

Za lokalne i automatske objekte: Konstruktor se poziva u trenutku kad se objekat definiše. Destruktor se poziva u trenutku napuštanja bloka u kojem je objekat

definisan.

Za statičke objekte: Konstruktor se poziva samo jednom - prilikom definisanja objekta. Destruktor se poziva samo nakon završetka izvršavanja funkcije main.

Page 24: Konstruktor Destruktor

Redoslijed konstruktora i destruktora

#include <iostream.h>class KD{ public: KD(int x) { data = x; cout << "Konst " << data; } ~KD() { cout<<"Dest "<<data<<endl; } private: int data;};

void create( void ){ KD kd5(5); cout << " (create lokalni)" << endl; static KD kd6(6); cout << " (create staticki)" << endl; KD kd7(7); cout << " (create lokalni)" << endl;}

KD kd1(1); // globalni objekat

main(){ cout <<" (ulaz u main)”<< endl; KD kd2(2); cout <<" (main: lokalni)”<<endl; static KD kd3(3); cout <<" (main: staticki)”<<endl; create(); KD kd4(4); cout <<" (main: lokalni)”<<endl; cout <<"Izlaz iz programa”<<endl;}

Konst 1 (ulaz u main)Konst 2 (main: lokalni)Konst 3 (main: staticki)Konst 5 (create lokalni)Konst 6 (create staticki)Konst 7 (create lokalni)Dest 7Dest 5Konst 4 (main: lokalni)Izlaz iz programaDest 4Dest 2Dest 6Dest 3Dest 1