Professional Documents
Culture Documents
OOP-C++-7-Reference I Kopirajući Konstruktor - 2018 PDF
OOP-C++-7-Reference I Kopirajući Konstruktor - 2018 PDF
Teme
Reference objekta
Korištenje referenci
Prosljeđivanje po vrijednosti vs. prosljeđivanje po referenci
Kopiranje objekata
Kopirajući konstruktor
Objektno-orijentirano programiranje
u programskom jeziku C++
3.12.2018. 1 3.12.2018. 2
3.12.2018. 3 3.12.2018. 4
3.12.2018. 5 3.12.2018. 6
Primjer: Prosljeđivanje objekta po vrijednosti - funkcije Primjer: Prosljeđivanje objekta po vrijednosti – poziv funkcije
void Povrsina1 (Kvadrat kvad){ // poziv po vrijednosti void main(){
Kvadrat kvd;
cout << "\n Stranica a u fiji1: " <<kvad.getA();
cout << "\n Pozivi fije1 (po vrijednosti, vodi) \n”;
cout << "\n Povrsina je " << kvad.getA() * kvad.getA();
Povrsina1(kvd);
kvad.setA(5); cout << "\n Stranica a nakon poziva fije1 (po vrijednosti, void): " << kvd.getA();
cout << "\n Stranica a u fiji1: " <<kvad.getA(); Povrsina2(kvd);
} cout << "\n Stranica a nakon poziva fije2 (po vrijednosti, vraća objekt): " << kvd.getA();
}
Kvadrat Povrsina2 (Kvadrat kvad){ // poziv po vrijednosti, povratni tip instanca Kvadrat
cout << "\n Stranica a u fiji2: " <<kvad.getA();
cout << "\n Povrsina je " << kvad.getA() * kvad.getA();
kvad.setA(10);
cout << "\n Stranica a u fiji2: " <<kvad.getA();
return kvad;
}
3.12.2018. 13 3.12.2018. 14
Primjer: Prosljeđivanje objekta po referenci - funkcije Primjer: Prosljeđivanje objekta po referenci – poziv funkcije
Kvadrat & Povrsina3 ( Kvadrat &kvad){ //poziv po referenci na objekt void main(){
Kvadrat kvd;
cout << "\n Stranica a u fiji3: " <<kvad.getA();
cout << "\n Poziv fije3 (reference) \n”;
cout << "\n Povrsina je " << kvad.getA()*kvad.getA();
Povrsina3(kvd);
kvad.setA(15); //- objekt nije zaštićen od promjena – preporuka const! cout << "\n Stranica a nakon poziva fije3 (reference): " << kvd.getA();
cout << "\n Stranica a u fiji3: " <<kvad.getA(); cout << "\n Poziv fije4 (pokazivaci) \n”;
return kvad; Povrsina4(kvd);
} cout << "\n Stranica a nakon poziva fije2 (pokazivaci): " << kvd.getA();
}
Kvadrat * Povrsina4 ( Kvadrat * kvad){ //poziv po pokazivacu - bolje na const objekt
cout << "\n Stranica a u fiji4: " <<kvad->getA();
cout << "\n Povrsina je " << kvad->getA()*kvad->getA();
kvad->setA(20); //ako je const nije moguće!
cout << "\n Stranica a u fiji4: " <<kvad->getA();
return kvad;
}
3.12.2018. 15 3.12.2018. 16
Prosljeđivanje objekata po vrijednosti i referenci Primjer: Prosljeđivanje objekta po referenci - const objekt
Prosljeđivanje instance klase (objekta) po vrijednosti poziva const Kvadrat & Povrsina3 (const Kvadrat & kvad){ //poziv po referenci na const objekt
podrazumijevani copy konstruktor koji stvara privremenu kopiju cout << "\n Stranica a u fiji3: " <<kvad.getA();
objekta.
cout << "\n Povrsina je " << kvad.getA()*kvad.getA();
Ukoliko funkcija vraćanja vrijednosti (objekt), kad funkcija završi s
radom još jednom se poziva copy konstruktor i potom dva puta //kvad.setA(15); //ako je const nije moguće!
destruktor da bi se uništile dvije novonastale privremene kopije cout << "\n Stranica a u fiji3: " <<kvad.getA();
proslijeđenog objekta funkciji. return kvad;
}
Reference i pokazivači su učinkovitiji, ali dozvoljeno im je mijenjati
vrijednosti varijabli stvarnih objekata – preporuka koristiti const const Kvadrat * Povrsina4 ( const Kvadrat * kvad) //poziv po pokazivaču na const objekt
pokazivač i const objekt
cout << "\n Stranica a u fiji4: " <<kvad->getA();
Const pokazivač može pozivati samo metode koje su u klasi definirane kao const
(ne mijenjaju vrijednost varijablama) cout << "\n Povrsina je " << kvad->getA()*kvad->getA();
Reference se ne mogu preusmjeriti na drugi objekt, stoga su one uvijek // kvad->setA(20); //ako je const nije moguće!
konstantne. cout << "\n Stranica a u fiji4: " <<kvad->getA();
return kvad;
}
3.12.2018. 18
Primjer: Prosljeđivanje objekta po referenci – const objekt Korištenje referenci i pokazivača (istovremeno)
void main(){
Kvadrat kvd; Dozvoljeno je deklarirati i pokazivače i reference unutar liste
cout << "\n Pozivi fije3 (reference) \n”;
parametara iste funkcije zajedno sa vrijednostima koje se prosljeđuju
po vrijednosti.
Povrsina3(kvd);
cout << "\n Stranica a nakon poziva fije3 (reference): " << kvd.getA(); Klasa * Funkcija (Klasa1 &objekt1, Klasa2 *objekt2, tip var);
cout << "\n Pozivi fije4 (pokazivaci) \n”;
Povrsina4(kvd); Voditi računa kod navođenja deklaracija pokazivača i referenci da ne dođe do
cout << "\n Stranica a nakon poziva fije4 (pokazivaci): " << kvd.getA(); zabune
Primjer:
}
Macka Tom;
Macka & rTom, rMica; // referenca je samo rTom, a rMica je objekt
3.12.2018. 19 20
21 3.12.2018. 22
3.12.2018. 23 3.12.2018. 24
3.12.2018. 25 3.12.2018. 26
3.12.2018. 27 3.12.2018. 28
3.12.2018. 29 3.12.2018. 30
Primjer: Kopiranje objekta i poziv funkcije po vrijednosti Primjer: Kopiranje objekta i poziv funkcije (2)
void povrsina1 (Kvadrat kvad){ // poziv po vrijednosti void povrsina1 (Kvadrat kvad){ // poziv po vrijednosti
cout << "\n Povrsina je " << kvad.getA()*kvad.getA(); cout << "\n Povrsina je " << kvad.getA()*kvad.getA();
} }
3.12.2018. 31 3.12.2018. 32
Primjer: Kopiranje objekta i poziv funkcije (3) Primjer: Kopirajući konstruktor- gomila
void main(){ #include <iostream> ParNepar::ParNepar(int broj){
Kvadrat *kvd, *kvd1; using namespace std; this->broj=broj;
kvd = new Kvadrat; }
//kvd1 = new Kvadrat; class ParNepar{
private: ParNepar::ParNepar(const ParNepar *kopija){
kvd1=kvd; broj=kopija->broj;
int broj;
cout<< endl<< &kvd << endl; public: }
cout<< &kvd1<< endl; ParNepar () : broj(0) {};
cout << "\n\n Poziv fije1 (po vrijednosti, void) ...\n"; ParNepar (int broj); void ParNepar::unos(){
ParNepa r(const ParNepar *); cout<<"Unesi broj: ";
povrsina1 (*kvd1);
void unos(); cin>>broj;
cout << "\n Poziv fije2 (po vrijednosti, vraca objekt)...\n"; }
void provjera();
povrsina2 (*kvd1); };
cout << "\n Poziv fije3 (reference) ...\n"; void ParNepar::provjera(){
povrsina3 (*kvd1); if(broj%2==0)
cout<<"Broj "<<broj<<" je paran"<<endl;
cout << "\n Poziv fije4 (pokazivaci) ...\n";
else cout<<"Broj "<<broj<<" je neparan"<<endl;
povrsina4 (&*kvd1); }
delete kvd, kvd1;
}
3.12.2018. 33 3.12.2018. 34
Primjer: objekti kao parametri funkcija Primjer: objekti kao parametri funkcija
#include <iostream> using namespace std; void main() {
class Sisavac { Sisavac* pMam = new Pas;
public: PokFunkcija(pMam);
Sisavac():iGod(1) { } RefFunkcija(*pMam); // * za vrijednost pokazivača
virtual ~Sisavac() { } VrFunkcija(*pMam);
virtual void GlasaSe() const { cout << “Sisavac se glasa!\n”; }
protected: pMam = new Macka;
int iGod; void RefFunkcija (Sisavac & rSisavac) { PokFunkcija(pMam);
rSisavac.GlasaSe();
}; RefFunkcija(*pMam);
}
class Pas : public Sisavac { VrFunkcija(*pMam);
public: void PokFunkcija (Sisavac * pSisavac) { delete pMam;
void GlasaSe() const { cout << “Vau! Vau!\n”; } pSisavac->GlasaSe(); }
}; }
void VrFunkcija (Sisavac vSisavac) { Prosljeđivanje nekog objekta po vrijednosti neće omogućiti pozivanje
class Macka: public Sisavac { vSisavac.GlasaSe(); implementacije virtualnih funkcija, nego će se pozvati funkciju u nadklasi.
public: }
Npr. Kod poziva po vrijednosti funkcija očekuje objekt Sisavca, tako da kompajler
void GlasaSe() const { cout << “Miau! Miau!\n”; }
poziva samo dio objekta Pas/Macka koji se odnosi na objekt nadklase (Sisavac) i
};
odgovarajuću funkciju GlasaSe() iz nadklase .
Sažetak Zadaci
3.12.2018. 45 3.12.2018. 46
Zadaci - rješenje
rectangle::rectangle (const rectangle& old_rc) {
height = old_rc.height;
width = old_rc.width;
xpos = old_rc.xpos;
ypos = old_rc.ypos;
}
void main() {
rectangle rc1(3.0, 2.0); // konstruktor
rectangle rc2(rc1); // korištenje kopirajućeg konstruktora
rectangle rc3 = rc1; // alternativna sintaksa za kopirajući konstruktor
// naredbe;
}