Professional Documents
Culture Documents
C++ Klase 3
C++ Klase 3
Banja Luka
Programski jezici 1
3. dio
Goran Banjac
goran.banjac@etfbl.net
12/3/15
Klase 3. dio
Sadraj
Prijatelji klase
Dodjeljivanje objekata lan po lan
Konstruktor kopije
Prijatelji klase
Prijatelj klase nije lan klase, ali ima pravo pristupa privatnim (i zatienim) lanovima
date klase.
};
Principi prijateljstva
Prijateljstvo se daruje, a ne uzima!
Da bi klasa A bila prijatelj klasi B, klasa B mora eksplicitno da deklarie da joj je klasa A prijatelj.
Prijateljstvo nije simetrino!
Ako je klasa A prijatelj klase B, to ne znai da je i klasa B prijatelj klasi A.
Prijateljstvo nije tranzitivno!
Ako je klasa A prijatelj klase B i ako je klasa B prijatelj klase C, to ne znai da je i klasa A prijatelj
klasi C.
Prijatelji klase
Primjer:
#include <iostream>
using namespace std;
class Data
{
friend void setX(Data &, int); // deklaracija prijatelja
public:
Data() { x=0; }
int getX() const { return x; }
private:
int x;
};
void setX(Data &dat, int val)
{
dat.x = val; // dozvoljeno: setX je prijatelj klase Data
}
int main()
{
Data d;
cout << "d.x nakon kreiranja: " << d.getX() << endl;
setX(d, 10); // postavi x pomocu prijatelja
cout << "d.x nakon poziva setX: " << d.getX() << endl;
}
d.x nakon kreiranja: 0
d.x nakon poziva setX: 10
Prijatelji klase
Primjer:
#include <iostream>
using namespace std;
class Complex
{
friend void dodaj(Complex &c, const Complex &z);
friend void dodaj(Complex &c, double d);
public: Complex(double r=0, double i=0) : re(r), im(i) {};
double getRe() { return re; }
double getIm() { return im; }
void print()
{
if (re!=0) { cout << re; if (im>0) cout << "+"; }
if (im!=0) { if (im!=1) cout << im; cout << "i"; }
}
private: double re, im;
};
Ako se koriste preklopljene
void dodaj(Complex &c, const Complex &z)
prijateljske funkcije, prototip
{ c.re += z.re; c.im += z.im; }
svake od tih funkcija mora biti
void dodaj(Complex &c, double d)
deklarisan kao prijatelj date
{ c.re += d; }
klase!
int main()
{
Complex a(2,3), b(1,-2);
a.print(); cout << " uvecano za "; b.print(); dodaj(a,b);
cout << " iznosi: "; a.print(); cout << endl;
a.print(); cout << " uvecano za 5.0 iznosi: "; dodaj(a,5.0); a.print();
}
Prijatelji klase
Primjer:
#include <iostream>
using namespace std;
class B
{
friend class A;
private: int data;
};
class A
{
public:
static void setB1(B &b, int data) { b.data = data; }
static int getB1(B &b) { return b.data; }
void setB2(B &b, int data) { b.data = data; }
int getB2(B &b) { return b.data; }
};
int main()
{
B b;
A::setB1(b,100); // preko ZF
cout << A::getB1(b) << endl;
A a;
a.setB2(b,200); // preko PF
cout << a.getB2(b);
}
100
200
t1
t2
class Time
{
public:
Time(int h=0,int m=0,int s=0)
{ hh=h; mm=m; ss=s; }
private:
int hh, mm, ss;
};
...
Time t1(12,25,30),t2;
t2=t1;
ss
30
30
ss
mm
25
25
mm
hh
12
12
hh
dat1 = 31.12.2004
dat2 = 1.1.2001
Nakon kopiranja
dat2 = 31.12.2004
#include <iostream>
using namespace std;
int main()
{
Test t1(100);
cout << "t1: "; t1.print();
Test t2;
t2 = t1;
cout << "t2: "; t2.print();
}
pi
0x3d2470
100
0x3d2470
Rezultat kopiranja
lan po lan
t2 = t1
t2
class Test
{
public:
Test(int i=0)
{
pi = new int;
*pi = i;
}
void print()
{
cout << "pi = " << pi;
cout << "\t*pi = " << *pi << endl;
}
private:
int *pi;
};
Pridrueni
dinamiki
objekat
Primjer:
pi
0x3d2470
*pi = 100
*pi = 100
0x3e2460
0x3e24e0
0x3e2460
100
0
0x3e24e0
t2 = t1
t1
pi
0x3e24e0
Pridrueni
dinamiki
objekat
#include <iostream>
using namespace std;
class Test
{
public:
Test(int i=0) { pi = new int(i); }
void print()
{
cout << "pi=" << pi;
cout << "\t*pi=" << *pi << endl;
}
~Test() { delete pi; }
private: int *pi;
};
int main()
{
Test t2;
cout << "t2 (inicijalno):\t";
t2.print();
{
Test t1(100); t2 = t1;
cout << "t2 (nakon dodjele):\t";
t2.print();
}
cout << "t2 (nakon brisanja t1):\t";
t2.print();
Pridrueni
dinamiki
objekat
Primjer:
t2 (inicijalno):
pi=0x3e2460
t2 (nakon dodjele):
pi=0x3e24e0
t2 (nakon brisanja t1): pi=0x3e24e0
*pi=0
*pi=100
*pi=0
Konstruktor kopije
konstruktora
class X
{
public:
X(const X &x);
};
Konstruktor kopije
t1
pi
0x3e2460
pi
0x3e24e0
pi
0x3e24f0
100
0x3e2460
100
0x3e24e0
100
0x3e24f0
t2
t3
#include <iostream>
using namespace std;
class Test
{
public:
Test(int i=0) { pi = new int(i); }
Test(Test &t) { pi = new int(*t.pi); }
void print() const
{
cout << "pi = " << pi;
cout << "\t*pi = " << *pi << endl;
}
~Test() { delete pi; }
private: int *pi;
};
int main()
{
Test t1(100);
cout << "t1 : "; t1.print();
Test t2=t1;
cout << "t2 : "; t2.print();
const Test t3(t2);
cout << "t3 : "; t3.print();
}
Pridrueni
dinamiki
objekat
Primjer:
t1 : pi = 0x3e2460
t2 : pi = 0x3e24e0
t3 : pi = 0x3e24f0
*pi = 100
*pi = 100
*pi = 100
Konstruktor kopije
Primjer:
Original: 0, 1, 2, 3, 4
Kopija:
0, 1, 2, 3, 4
#include <iostream>
using namespace std;
class Niz
{
public: Niz(int nn=1)
{
if (nn<1) nn=1; n=nn; data=new int[n];
for (int i=0; i<n; i++) data[i]=i;
}
Niz(const Niz &original)
{
n=original.n; data=new int[n];
for (int i=0; i<n; i++) data[i]=original.data[i];
}
void print() const
{
for (int i=0; i<n; i++) { cout << data[i]; if (i<n-1) cout << ", "; }
}
~Niz() { delete [] data; }
private: int n; int *data;
};
int main()
{
const Niz original(5); cout << "Original: "; original.print(); cout << endl;
Niz kopija(original); cout << "Kopija:
"; kopija.print();
cout << endl;
}
Konstruktor kopije
Primjer:
#include <iostream>
Kopija: Banja Luka
using namespace std;
class String
{
public:
String(char *t)
{
int bz=0; while (*(t+bz)) bz++;
s = new char[bz+1];
while (bz>=0) { *(s+bz)=*(t+bz); bz--; }
}
String(const String &original)
{
int bz=0; while (*(original.s+bz)) bz++;
s = new char[bz+1];
while (bz>=0) { *(s+bz)=*(original.s+bz); bz--; }
}
void print() const { cout << s << endl; }
~String() { delete [] s; }
private: char *s;
};
int main()
{
const String original("Banja Luka"); cout << "Original: "; original.print();
String kopija(original); cout << "Kopija: "; kopija.print();
}
Konstruktor kopije
Primjer:
#include <iostream>
Kopija: Banja Luka
#include <cstring>
using namespace std;
class String
{
public:
String(char *t)
{
s = new char[strlen(t)+1];
strcpy(s,t);
}
String(const String &original)
{
s = new char[strlen(original.s)+1];
strcpy(s,original.s);
}
void print() const { cout << s << endl; }
~String() { delete [] s; }
private: char *s;
};
int main()
{
const String original("Banja Luka"); cout << "Original: "; original.print();
String kopija(original); cout << "Kopija: "; kopija.print();
}
Konstruktor kopije
Tipino aktiviranje konstruktora kopije je kod kreiranja automatskih
objekata koji predstavljaju formalne argumente funkcija!
Primjer 1:
Primjer 2:
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << '1'; }
A(A &a) { cout << '2'; }
~A() { cout << '0'; }
};
void f(A &a) { A b=a; }
int main()
{
A a; f(a);
}
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << '1'; }
A(A &a) { cout << '2'; }
~A() { cout << '0'; }
};
void f(A a) { A b=a; }
int main()
{
A a; f(a);
}
1200
122000
Konstruktor kopije
Tipino aktiviranje konstruktora kopije je kod kreiranja privremenih
objekata pri vraanju rezultata iz funkcije!
Primjer 1:
Primjer 2:
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << "K "; }
~A() { cout << "D "; }
};
A f()
{
A a, b, c;
return b;
}
int main()
{ A b; b=f(); }
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << "K "; }
~A() { cout << "D "; }
};
A f(int x)
{
A b, c;
if (x) return b;
else return c;
}
int main()
{ A b; b=f(1); }
K K K K D D D D
K K K D D D D
Konstruktor kopije
Primjer:
#include <iostream>
using namespace std;
class Razlomak
{
friend Razlomak zbir(const Razlomak &, const Razlomak &);
friend void print(const Razlomak &);
public: Razlomak(int b=0, int n=1) : broj(b), imen(n) {}
private: int broj, imen;
};
Razlomak zbir(const Razlomak &a, const Razlomak &b)
{
Razlomak t;
t.broj = a.broj * b.imen + a.imen * b.broj;
t.imen = a.imen * b.imen;
return t;
}
1/3 + 7/8 = 29/24
void print(const Razlomak &r)
{
if (r.broj==0) cout << 0;
else cout << r.broj << '/' << r.imen;
}
int main()
{
Razlomak c(1,3), d(7,8), x;
print(c); cout << " + "; print(d); x = zbir(c,d); cout << " = "; print(x);
}