Reprezentacja klas z pomoc diagramów UML (Unified Modeling Language)
Przykładowy diagram reprezentujący klasę Punkt
Obiekty klasy punkt zawierają dwa atrybuty - współrzędną x oraz współrzędną y
Oba atrybuty są typu double.
Powyższy rysunek odpowiada następującemu fragmentowi kodu w języku JAVA
plik Punkt.java
class Punkt {
//atrybuty
double m_x;
double m_y;
//pusty konstuktor
Punkt()
{}
}
Powyższy rysunek odpowiada również następującemu fragmentowi kodu w języku C++
plik Punkt.h
class Punkt {
public:
//atrybuty
double m_x;
double m_y;
//pusty konstruktor
Punkt();
};
plik Punkt.cpp
Punkt::Punkt()
{
}
Teraz dwa konstruktory
Powyższy rysunek odpowiada następującemu fragmentowi kodu w języku JAVA
plik Punkt.java
class Punkt {
//atrybuty
double m_x;
double m_y;
//pusty konstuktor
Punkt()
{}
//konstuktor z argumentami
Punkt(double X, double Y)
{
m_x=X;
m_y=Y;
}
}
Powyższy rysunek odpowiada również następującemu fragmentowi kodu w języku C++
plik Punkt.h
class Punkt {
public:
//atrybuty
double m_x;
double m_y;
//pusty konstruktor
Punkt()
//konstruktor z argumentami
Punkt(double X, double Y);
};
plik Punkt.cpp
Punkt::Punkt()
{
}
Punkt::Punkt(double X, double Y)
{
m_x=X; m_y=Y;
}
Za pomocą diagramów UML można zaznaczać zależności pomiędzy klasami.
Kwadrat skłąda się z czterech punktów, A,B,C,D
Kod w JAVIE
class Kwadrat {
Punkt m_A;
Punkt m_B;
Punkt m_C;
Punkt m_D;
}
Kod w C++
class Kwadrat {
public:
Punkt m_A;
Punkt m_B;
Punkt m_C;
Punkt m_D;
};
To samo ale z wyświetlonymi na diagramie konstruktorami
Kod w JAVIE
Plik Kwadrat.java
class Kwadrat {
Kwadrat(Punkt A, Punkt B, Punkt C, Punkt D)
{
m_A = A;
m_B = B;
m_C = C;
m_D = D;
}
Punkt m_A;
Punkt m_B;
Punkt m_C;
Punkt m_D;
}
Kod w C++
Plik Kwadrat.h
class Kwadrat {
public:
Kwadrat(Punkt A, Punkt B, Punkt C, Punkt D);
Punkt m_A;
Punkt m_B;
Punkt m_C;
Punkt m_D;
};
Plik Kwadrat.cpp
Kwadrat::Kwadrat(Punkt A, Punkt B, Punkt C, Punkt D)
{
m_A = A;
m_B = B;
m_C = C;
m_D = D;
}
Konstrukcja obiektu klasy kwadrat
Kod w JAVA
class Aplikacja {
public static void main(String args[]) {
Punkt A = new Punkt(0.0,0.0);
Punkt B = new Punkt(1.0,0.0);
Punkt C = new Punkt(0.0,1.0);
Punkt D = new Punkt(1.0,1.0);
Kwadrat kwadrat = new Kwadrat(A,B,C,D);
}
}
A, B, C, D oraz m_A, m_B, m_C, m_D to są tylko podwójne nazwy 4 obiektów (referencje)
W konstruktorze klasy Kwadrat zapamiętywane są te nazwy, nie są tworzone 4 nowe obiekty
class Kwadrat {
Kwadrat(Punkt A, Punkt B, Punkt C, Punkt D)
{
m_A = A;
m_B = B;
m_C = C;
m_D = D;
}
Punkt m_A; //m_A to tylko druga nazwy obiektu klasy Punkt
Punkt m_B;
Punkt m_C;
Punkt m_D;
}
W C++ sytuacja wygląda trochę inaczej
Kod w C++
Plik Aplikacja.cpp
int main(int argc, char* argv[])
{
Punkt A(0.0,0.0);
Punkt B(1.0,0.0);
Punkt C(0.0,1.0);
Punkt D(1.0,1.0);
Kwadrat kwadrat(A,B,C,D);
}
Ale uwaga! W C++ to nie koniec!
A,B,C,D w C++ to są cztery osobne obiekty
Podobnie m_A, m_B, m_C i m_D to są cztery nowe obiekty
To nie są cztery nowe nazwy obiektów A,B,C,D, tylko cztery nowe obiekty
Zobaczmy co sie dzieje w konstruktorze
Co sie dzieje w konstruktorze
Kod w C++
class Kwadrat {
Kwadrat(Punkt A, Punkt B, Punkt C, Punkt D)
{
m_A = A;
m_B = B;
m_C = C;
m_D = D;
}
Punkt m_A; //m_A to nowy obiekt klasy Punkt
Punkt m_B;
Punkt m_C;
Punkt m_D;
}
Tworzone są kopie!!! obiektów Punkt.
Obiekt Punkt A jest kopiowany do obiektu m_A
Obiekt Punkt B jest kopiowany do obiektu m_B
Obiekt Punkt C jest kopiowany do obiektu m_C
Obiekt Punkt D jest kopiowany do obiektu m_D
Jeśli w C++ w kwadracie użyjemy referencji zamiast wskaźników do punktów,
sytuacja wyglądać będzie tak samo jak w JAVIE
Kod w C++
class Kwadrat {
Kwadrat(Punkt& A, Punkt& B, Punkt& C, Punkt& D)
{
m_A = A;
m_B = B;
m_C = C;
m_D = D;
}
//teraz m_A to druga nazwa (referencja) obiektu klasy Punkt
Punkt& m_A;
//podobnie m_B, m_C oraz m_D
Punkt& m_B;
Punkt& m_C;
Punkt& m_D;
}
Teraz m_A, m_B, m_C oraz m_D to są tylko drugie nazwy obiektów klasy Punkt
Konstruktor w C++ nie tworzy nowych obiektów!!!
Różnica pomiędzy obiektem statycznym a wskaźnikiem w C++
Na diagramach UML zawieranie obiektu statycznego zaznaczone jest zamalowanym na czarno diamentem
Kod w C++
class Kwadrat {
public:
Punkt m_A;
Punkt m_B;
Punkt m_C;
Punkt m_D;
}
Na diagramach UML przechowywanie wskaźnika do obiektu (kartki z jego adresem) zaznaczone jest pustym (nie zamalowanym) diamentem
Kod w C++
class Kwadrat {
public:
Punkt* m_A;
Punkt* m_B;
Punkt* m_C;
Punkt* m_D;
}
Musimy przepisać konstruktor obiektu klasy kwadrat, tak żeby dostawał 4 wskaźniki
Konstrukcja obiektu klasy kwadrat za pomocą wskaźników
Kod w C++
Plik Kwadrat.h
class Kwadrat {
public:
Kwadrat(Punkt* A, Punkt* B, Punkt* C, Punkt* D);
Punkt* m_A;
Punkt* m_B;
Punkt* m_C;
Punkt* m_D;
};
Plik Kwadrat.cpp
Kwadrat::Kwadrat(Punkt* A, Punkt* B, Punkt* C, Punkt* D)
{
m_A = A;
m_B = B;
m_C = C;
m_D = D;
}
Kod w C++
Plik Aplikacja.cpp
int main(int argc, char* argv[])
{
Punkt* A = new Punkt(0.0,0.0);
Punkt* B = new Punkt(1.0,0.0);
Punkt* C = new Punkt(0.0,1.0);
Punkt* D = new Punkt(1.0,1.0);
Kwadrat kwadrat(A,B,C,D);
}
Tym razem tworzone są cztery nienazwane obiekty klasy Punkt
Każda operacja
new Punkt(...)
zwraca wskaźnik do obiektu klasy Punkt (czyli kartke z adresem tego obiektu w pamięci)
Mamy więc cztery nienazwane obiekty klasy Punkt i cztery kartki
A, B, C, D każda zawierająca adres jednego z tych obiektów.
Gdy tworzymy obiekt kwadrat klasy Kwadrat, to wywoływany jest konstruktor klasy Kwadrat.
Konstruktor ten dostaje cztery wskaźniki do czterech obiektów klasy Punkt
(cztery kartki A,B,C,D z adresami czterech obiektów).
Klasa kwadrat posiada własne cztery wskaźniki (kartki m_A, m_B, m_C, m_D które są jeszcze niezapisane)
Konstruktor przepisuje adres z kartki A na kartkę m_A
z kartki B na kartkę m_B
z kartki C na kartkę m_C
z kartki D na kartkę m_D
Krok dalej - z kwadratów budujemy sześcian
Kod w C++
Plik Kwadrat.h
class Kwadrat {
public:
Kwadrat(Punkt* A, Punkt* B, Punkt* C, Punkt* D);
Punkt* m_A;
Punkt* m_B;
Punkt* m_C;
Punkt* m_D;
};
Plik Kwadrat.cpp
Kwadrat::Kwadrat(Punkt* A, Punkt* B, Punkt* C, Punkt* D)
{
m_A = A;
m_B = B;
m_C = C;
m_D = D;
}
Kod w JAVIE
class Szescian {
Kwadrat m_gora;
Kwadrat m_dol;
Kwadrat m_lewo;
Kwadrat m_prawo;
Kwadrat m_przod;
Kwadrat m_tyl;
}
Kod w C++
class Szescian {
public:
Kwadrat m_gora;
Kwadrat m_dol;
Kwadrat m_lewo;
Kwadrat m_prawo;
Kwadrat m_przod;
Kwadrat m_tyl;
};