class Zesp

Transkrypt

class Zesp
Funkcje składowe (metody)
class Punkt
{
private:
int x, y;
public:
void Rysuj()
{
/* rysowanie */
};
class Punkt
{
private:
int x, y;
public:
void Rysuj();
};
void Punkt::Rysuj()
{
/* rysowanie */
}
definicja funkcji
wewnątrz ciała klasy
}
funkcja otwarta
definicja funkcji
poza ciałem klasy
Wywołanie funkcji składowej
Funkcja składowa klasy może być aktywowana
(wywołana) tylko na rzecz obiektu tej samej klasy.
<nazwa obiektu>.<nazwa_funkcji> (<argumenty>) ;
PRZYKŁAD:
Punkt p;
p.Rysuj();
Funkcja składowa
class Zesp
{
public:
Zesp();
Zesp(float a, float b);
private:
float re, im;
};
Zesp::Zesp()
{
re = im = 0;
}
Zesp::Zesp(float a, float b)
{
re = a; im = b;
}
Problem: klasę Zesp należy uzupełnić
o operację dodawania dwóch liczb zespolonych.
Funkcja składowa
class Zesp
{
public:
Zesp();
Zesp(float a, float b);
Zesp dodaj(Zesp z);
private:
float re, im;
};
void main()
{
Zesp a(0, 1), b(1, 0), c;
c = a.dodaj(b);
}
Zesp::Zesp()
{
re = im = 0;
}
Zesp::Zesp(float a, float b)
{
re = a; im = b;
}
Zesp Zesp::dodaj(Zesp z)
{
Zesp wynik;
wynik.re = re+z.re;
wynik.im = im+z.im;
return wynik;
}
return Zesp(re+z.re, im+z.im);
Przykład – wersja strukturalna
#include <iostream>
using namespace std;
// definicja struktury
typedef struct zespolone
{
float re, im; // pola struktury
} Zespolone;
// dodawanie liczb zespolonych
Zespolone dodaj (Zespolone a, Zespolone b)
{
Zespolone c;
c.re = a.re + b.re;
c.im = a.im + b.im;
return c;
}
void main()
{
Zespolone a = {0, 1}, b = {1, 0}, c;
c = dodaj(a, b);
cout << "c = "<< c.re << " + j" << c.im << endl;
}
Przykład – wersja obiektowa
#include <iostream>
using namespace std;
class Zesp
{
public:
Zesp() { re = 0; im = 0; }
Zesp (float Re, float Im) { re = Re;
im = Im; }
Zesp dodaj (Zesp z)
{ return Zesp(re+z.re, im+z.im); }
void drukuj()
{ cout << re << ” + j” << im; }
private:
float re, im; // pola klasy
};
void main()
{
Zesp a(0, 1), b(1, 0), c;
c = a.dodaj(b);
c.drukuj();
}
Wskaźnik this
Wskaźnik this zawiera adres obiektu bieżącego
(tzn. obiektu, na rzecz którego wywołano funkcję składową).
Wskaźnik ten jest dostępny wyłącznie wewnątrz funkcji
składowych niestatycznych.
this
*this
-
adres obiektu
obiekt (wartość obiektu)
Słowo kluczowe this jest stosowane wszędzie tam, gdzie
w funkcji składowej istnieje potrzeba zwrócenia wskaźnika
na obiekt lub wartości obiektu.
return this
return *this
-
adres obiektu
obiekt
Funkcja składowa i wskaźnik this
class Zesp
{
public:
Zesp();
Zesp(float a, float b);
private:
float re, im;
};
Zesp::Zesp()
{
re = im = 0;
}
Zesp::Zesp(float a, float b)
{
re = a; im = b;
}
Problem: klasę Zesp należy uzupełnić
o operację powiększania liczby zespolonej
o inną liczbę zespoloną.
Zastosowanie wskaźnika this
Zesp Zesp::powieksz(Zesp z)
{
re += z.re;
// this->re += z.re;
im += z.im;
// (*this).im += z.im;
return *this;
}
zwrócenie zmodyfikowanego obiektu
void main()
{
Zesp z1(2, 3), z2(3, 5);
z1.powieksz(z2);
}
Funkcje zaprzyjaźnione
Funkcja zaprzyjaźniona z klasą to zwykła funkcja
„zewnętrzna” lub funkcja składowa innej klasy, zadeklarowana
za pomocą słowa kluczowego friend.
Cechy funkcji zaprzyjaźnionej:
• nie należy do klasy, nie jest składową klasy
(wniosek: nie można odwołać się do niej poprzez nazwę
kwalifikowaną)
• nie można jej aktywować na rzecz obiektu
• otrzymuje jako argument lub zwraca jako wynik obiekt klasy
z którą jest zaprzyjaźniona
• pod względem dostępu do składowych prywatnych ma
takie same prawa jak funkcja składowa
• funkcja może być zaprzyjaźniona z wieloma klasami
(obiekty tych klas to argumenty lub wynik funkcji)
Funkcja składowa czy zaprzyjaźniona?
class Zesp
{
public:
Zesp();
Zesp(float a, float b);
private:
float re, im;
};
Zesp::Zesp()
{
re = im = 0;
}
Zesp::Zesp(float a, float b)
{
re = a; im = b;
}
Problem: klasę Zesp należy uzupełnić
o operację wydruku liczby zespolonej.
Funkcja składowa
ROZWIĄZANIE 1:
class Zesp
{
public:
Zesp();
Zesp(float a, float b);
float get_re();
float get_im();
private:
float re, im;
};
funkcje udostępniające
Zesp::Zesp()
{
re = im = 0;
}
Zesp::Zesp(float a, float b)
{
re = a; im = b;
}
float Zesp::get_re()
{
return re;
}
float Zesp::get_im()
{
return im;
}
void main()
{
Zesp z(2, 5);
cout << ‘(‘ << z.get_re() << ‘,‘ << z.get_im() << ‘)‘;
}
Funkcja składowa
ROZWIĄZANIE 2:
class Zesp
{
public:
Zesp();
Zesp(float a, float b);
void drukuj();
private:
float re, im;
};
void main()
{
Zesp z(2, 5);
z.drukuj();
}
Zesp::Zesp()
{
re = im = 0;
}
Zesp::Zesp(float a, float b)
{
re = a; im = b;
}
void Zesp::drukuj()
{
cout << ‘(‘ << re << ‘,‘;
cout << im << ‘)‘;
}
Funkcja zaprzyjaźniona
ROZWIĄZANIE 3:
class Zesp
{
public:
Zesp();
Zesp(float a, float b);
friend void drukuj(Zesp z);
private:
float re, im;
};
void main()
{
Zesp z(2, 5);
drukuj(z);
}
Zesp::Zesp()
{
re = im = 0;
}
Zesp::Zesp(float a, float b)
{
re = a; im = b;
}
void drukuj(Zesp z)
{
cout << ‘(‘ << z.re << ‘,‘;
cout << z.im << ‘)‘;
}
Funkcja zaprzyjaźniona
ROZWIĄZANIE 4:
void drukuj1(Zesp z)
{
cout << ‘(‘ << z.re << ‘,‘;
cout << z.im << ‘)‘;
}
class Zesp
{
public:
Zesp();
Zesp(float a, float b);
void drukuj2(Zesp &z)
friend void drukuj1(Zesp z); {
friend void drukuj2(Zesp &z);
cout << ‘(‘ << z.re << ‘,‘;
friend void drukuj3(Zesp *z);
cout << z.im << ‘)‘;
}
private:
float re, im;
};
void main()
{
Zesp z(2, 5);
drukuj1(z); drukuj2(z);
}
void drukuj3(Zesp *z)
{
cout << ‘(‘ << z->re;
cout << ‘,‘ << z->im << ‘)‘;
}
drukuj3(&z);
Funkcja składowa a zaprzyjaźniona
Zesp Zesp::dodaj(Zesp z)
{
Zesp wynik;
Funkcja składowa klasy
wynik.re = re + z.re;
wynik.im = im + z.im;
return wynik;
}
return Zesp(re + z.re, im + z.im);
Zesp odejmij(Zesp z1, Zesp z2)
{
Zesp wynik;
Funkcja zaprzyjaźniona
wynik.re = z1.re – z2.re;
z klasą
wynik.im = z1.im - z2.im;
return wynik;
}
return Zesp(z1.re - z2.re, z1.im - z2.im);
Porównanie
Funkcja składowa
klasy
deklaracja
definicja
wywołanie
(aktywacja)
Funkcja zaprzyjaźniona
z klasą
Zesp dodaj(Zesp z);
friend Zesp odejmij(Zesp z1,
Zesp z2);
Zesp Zesp::dodaj(Zesp z)
{
Zesp wynik;
wynik.re = re+z.re;
wynik.im = im+z.im;
return wynik;
}
Zesp odejmij(Zesp z1, Zesp z2)
{
Zesp wynik;
wynik.re = z1.re - z2.re;
wynik.im = z1.im – z2.im;
return wynik;
}
Zesp z1, z2, z3;
z3 = z1.dodaj(z2);
Zesp z1, z2, z3;
z3 = odejmij(z1, z2);
Składowe statyczne
Deklarowane są za pomocą słowa kluczowego static.
Składowe statyczne:
• pola statyczne
• funkcje statyczne
Pole statyczne klasy:
• jest wspólne dla wszystkich obiektów tej klasy
• jest widoczne we wszystkich obiektach tej klasy, ale
w pamięci istnieje tylko jeden egzemplarz tego pola
• istnieje niezależnie od tworzonych obiektów
(„zmienna globalna” dla klasy)
• istnieje i można się do niego odwoływać nawet jeśli
nie utworzono jeszcze żadnego obiektu klasy
Dostęp do pól statycznych:
• taki jak do zwykłych pól składowych
• dodatkowo: poza klasą, podczas inicjalizacji pola
• dodatkowo: za pomocą funkcji statycznych
Inicjalizacja pól statycznych
• pola statyczne inicjalizuje się poza klasą używając
pełnej nazwy kwalifikowanej
• pola statyczne nie mogą być inicjalizowane przez konstruktor
(są wspólne dla wszystkich obiektów klasy, a nie dotyczą
konkretnego obiektu - egzemplarza, instancji klasy)
• prywatne pole statyczne poza klasą można tylko zainicjalizować
(poza klasą nie ma do niego bezpośredniego dostępu
poprzez jego nazwę)
• publiczne pole statyczne poza klasą jest dostępne
poprzez pełną nazwę kwalifikowaną
Funkcje statyczne
• funkcje statyczne służą do wykonywania operacji
na polach statycznych
• wewnątrz funkcji statycznej widoczne są tylko pola statyczne
- nie są widoczne zwykłe, niestatyczne pola składowe
- nie są widoczne niestatyczne funkcje składowe
Składowe statyczne
class Zesp
{
public:
Zesp();
Zesp(float a, float b);
~Zesp();
static int Ile();
private:
float re, im;
static int licznik;
};
void main()
{
cout << Zesp::Ile();
Zesp z1, z2(2, 3);
cout << Zesp::Ile();
}
int Zesp::licznik = 0;
Zesp::Zesp()
{
re = im = 0; licznik++;
}
Zesp::Zesp(float a, float b)
{
re = a; im = b;
licznik++;
}
Zesp::~Zesp()
{ licznik--;
}
int Zesp::Ile()
{
return licznik;
}