• Nie Znaleziono Wyników

Wstęp do programowania obiektowego

N/A
N/A
Protected

Academic year: 2021

Share "Wstęp do programowania obiektowego"

Copied!
30
0
0

Pełen tekst

(1)

Wstęp do programowania obiektowego

Wykład 5

Słowo kluczowe const

Przeładowywanie operatorów strumieniowych Klasa string

Agregacja i kompozycja

(2)

SŁOWO KLUCZOWE

CONST

(3)

Słowo kluczowe const

Słowem kluczowym const w C++

deklaruje się stałe.

Obiekty zadeklarowane jako const mogą być inicjalizowane, natomiast nie mogą być przypisywane poza ich inicjalizacją, np.

const int b = 7;

b = 12; //błąd kompilacji

Argumenty funkcji zadeklarowane jako const

nie mogą być zmieniane - przy przekazywaniu

przez referencję (przy przekazywaniu przez

(4)

Metody z przyrostkiem const

void nazwa(…) const – taka metoda nie może nic zmieniać w obiekcie, może tylko czytać

class Punkt { float x,y;

float przesun(float dx, float dy) const {

x += dx; //błąd kompilacji y += dy; //błąd kompilacji }

}

(5)

Wskaźniki i słowo const

const int * wsk = &a;

wsk jest wskaźnikiem do obiektu stałego typu int, czyli można wskaźnikiem wsk pokazywać na różne zmienne, ale nie można ich modyfikować za pomocą wsk.

int * const wsk = &a;

wsk jest stałym wskaźnikiem do zmiennej int, czyli można modyfikować obiekt na który wskazuje, ale nie można

pokazywać tym wskaźnikiem na inny obiekt niż ten, na który został ustawiony w czasie deklaracji.

const int * const wsk = &a;

wsk jest stałym wskaźnikiem do stałej int, ani nie można

modyfikować obiektu pokazywanego przez wskaźnik, ani

nie można pokazać tym wskaźnikiem na inny obiekt.

(6)

Wskaźniki i słowo const - przykłady

int a, b;

const int * wsk = &a;

wsk = &b;

*wsk = 6; //error: assignment of read-only location *wsk ---

int a, b;

int * const wsk = &a;

wsk = &b; //error: assignment of read-only variable wsk

*wsk = 6;

---

int a, b;

const int * const wsk = &a;

wsk = &b; //error: assignment of read-only variable wsk

(7)

PRZEŁADOWYWANIE OPERATORÓW

STRUMIENIOWYCH << >>

(8)

Przeładowywanie operatora strumieniowego

<<

Definicja funkcji operatorowej:

ostream& operator<<(ostream& os, const Zespolona& z) { os << „(” << z.re << „,” << z.im << „)”;

return os; }

Przykładowe użycie:

Zespolona z(5.5, 3.1);

cout << z;

Taką funkcję operatorową definiujemy poza klasą, ale musimy ją z klasą zaprzyjaźnić, jeżeli korzysta ona z prywatnych składowych klasy:

friend ostream& operator<<(ostream&, const Zespolona

(9)

Przeładowywanie operatora strumieniowego >>

Definicja:

istream& operator>>(istream& is, Zespolona& z) {

is >> z.re >> z.im;

return is;

}

Przykładowe użycie:

Zespolona z(5.5, 3.1);

cout << z;

Zaprzyjaźniamy funkcję z klasą w miarę potrzeby.

Liczby możemy wprowadzić w jednej linijce oddzielone

spacjami, albo po każdej przyciskając <Enter>.

(10)

KLASA STRING

(11)

Klasa string

 Stanowi wygodną obiektową alternatywę dla tzw. c-stringa, czyli tablicy znaków typu char, zakończonej zerem

(reprezentacja napisów w czystym strukturalnym C).

Klasa string umożliwia jednolity,

niezależny od systemu i bezpieczny

sposób na składowanie i manipulowanie napisami.

 Zdefiniowana jest m.in. w pliku

nagłówkowym string.h, iostream.h, itp.

(12)

Przykłady nadania wartości

string n1("tekst1 "); //konstruktorem

string n2 = "tekst2 "; //podstawieniem stałej napisowej string n3 = n1; //podstawieniem innego stringa cout << n1 << n2 << n3;

(13)

Operatory

Klasa string ma zdefiniowane operatory:

= przypisanie

== równość

!= nierówność

< > <= >= porządek słownikowy + += łączenie napisów

[] (indeksowanie) dostęp do poszczególnych

znaków

(14)

Wybrane metody klasy string

empty() Zwraca true jeżeli napis jest pusty.

size(), length() Zwraca ilość znaków w napisie.

at(int) Zwraca znak o podanym

położeniu, podobnie jak operator [ ], clear() Usuwa wszystkie znaki z napisu.

erase(...) Usuwa podciąg.

find(...) Znajduje podciąg w napisie

swap(string, string) Zamienia dwa stringi wartościami substr(...) Zwraca podciąg napisu

append(...) Dodaje zadany napis na końcu

innego

(15)

Poruszanie się po stringu iteratorem

Iterator – metoda (niezawodnego) poruszania się po zbiorze danych tego samego typu (tutaj znaki typu char)

using namespace std;

#include <iostream>

#include <string>

int main () {

string str ("Napis testowy");

for (string::iterator it=str.begin(); it!=str.end(); it++) cout << *it;

cout << '\n';

(16)

Poruszanie się po stringu iteratorem

Iterator – metoda (niezawodnego) poruszania się po zbiorze danych tego samego typu (tutaj znaki typu char)

using namespace std;

#include <iostream>

#include <string>

int main () {

string str ("Napis testowy");

for (string::iterator it=str.begin(); it!=str.end(); it++)

cout << *it;

cout << '\n';

Deklaracja iteratora o

nazwie it

it jest ustawiane na początku

tekstu

...dopóki it nie jest na

końcu tekstu

Przesuwamy it o jeden

znak w prawo

(17)

… i poruszanie się standardowo (indeksowaniem)

for (int i = 0; i<str.size(); i++)

cout << str[i];

(18)

AGREGACJA

(19)

Agregacja

Agregacja w programowaniu

obiektowym to sytuacja, gdy tworzy się nową klasę, używając jako

zmiennych składowych obiektów innych klas (tzw. „obiektów

składowych").

 Nowa klasa może być zbudowana z dowolnej liczby obiektów (dowolnych typów). Liczba powiązanych obiektów może też się zmieniać w czasie.

19

(20)

Przykład agregacji

class Staw

{ Kaczka* kaczki[20];

};

class Kaczka { };

Staw Kaczka

0..1 0..*

 Na diagramach UML agregację oznacza się pustym rombem.

 Kaczka może istnieć samodzielnie, lub być przypisana

(21)

 Agregacja jest określana jako relacja typu "zawiera".

Agregacja jest często przedstawiana w opozycji do dziedziczenia, które

polega na uszczegóławianiu typu ogólnego w celu utworzenia typu

szczególnego. Agregacja nie tworzy

podtypu, lecz nowy typ.

(22)

KOMPOZYCJA

(23)

Kompozycja jest szczególnym przypadkiem agregacji. Oznacza składanie się obiektu z obiektów

składowych, które nie mogą istnieć bez obiektu głównego.

 część może należeć tylko do jednej całości;

 usunięcie całości powoduje automatyczne usunięcie wszystkich jej części.

Kompozycja jest relacją typu „posiada”.

Związek między obiektami jest silny.

(24)

Przykład kompozycji

class Silnik {};

class Samochod { Silnik* sil;

public:

Samochod() {sil = new Silnik();}

~Samochod() {delete sil;}

};

Samochód nie może istnieć bez Silnika, tworzy Silnik w konstruktorze, a niszczy w destruktorze

Realizacja kompozycji zwykle należy do programisty (zapewnienie odpowiedniego tworzenia oraz niszczenia obiektów składowych)

Na diagramach UML kompozycję oznacza się wypełnionym

Samochod Silnik

0..1 1

(25)

Kompozycja a agregacja

Kompozycją określa się sytuację, kiedy

• kompozyt (i czasem komponent) nie mogą istnieć oddzielnie,

• liczność komponentów nie zmienia się,

• związek między obiektami jest bardzo silny (np.

Odcinek i Trójkąt).

Agregacją określa się sytuację, kiedy

• kompozyt i komponent mogą istnieć bez siebie,

• liczność komponentów może się zmieniać dynamicznie,

• związek między obiektami jest o wiele słabszy

niż w kompozycji (np. Książka i Biblioteka).

(26)

Liczności w UML

Liczności obiektów na diagramach UML oznaczamy przedziałami, gdzie mogą występować liczby całkowite oraz

gwiazdka, która oznacza dowolną ilość (również zero).

Samochod Silnik

0..1 1

Staw Kaczka

0..1 0..*

(27)

Agregacja rekursywna

Agregacja może być rekursywna, czyli zawierać obiekty (lub odwołania do obiektów) tego samego typu.

Przykład: węzeł drzewa binarnego:

class Node{

Node *left, *right;

int liczba;

};

(28)

#include <stdio.h>

#include <stdlib.h>

#include <iostream>

using namespace std;

class Node{

public:

Node *left, *right;

int liczba;

Node (int ii):liczba(ii){}

};

ostream& operator<<(ostream& os, const Node& z) {

os << "(" << z.liczba << ")\n";

return os;

}

int main() {

Node n = Node(3);

(29)

Uniwersytet składa się z Wydziałów, które nie mogą istnieć samodzielnie i muszą być

przypisane do jakiegoś Uniwersytetu (kompozycja).

 Każdy Wydział ma pewną liczbę pracujących w nim Profesorów (minimum 5), którzy nie są aż tak mocno powiązani z Wydziałem (mogą istnieć samodzielnie oraz być powiązani z jednym lub dwoma Wydziałami – agregacja).

Uniwersytet 1 1..20 Wydział 0..2 5..* Profesor

Kompozycja + agregacja

(30)

Kompozycja trójkąta z 3

punktami

Cytaty

Powiązane dokumenty

 Standardowo wywoływany jest konstruktor bezparametrowy (lub domyślny) klasy nadrzędnej..  Aby do konstrukcji podobiektu klasy bazowej

 Przeszukiwany jest stos wywołań funkcji w poszukiwaniu takiej, która zawiera obsługę wyjątku danego typu (czyli odpowiednią instrukcję catch).. ◦ Jeżeli

• Parametrami szablonów mogą być również szablony klas, jako tak zwane szablony parametrów szablonów.. Stack&lt;int, std::vector&gt;

 OutputIterator set_union (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result);.  OutputIterator

Model dziedziny (uzupełniony): klasy, atrybuty klas oraz

 Jednostka programu, która zadeklarowała instancję klasy (obiekt), ma dostęp do publicznych bytów tej klasy, ale tylko poprzez tę instancję.  Każda instancja klasy ma

 Symbole pojawiające się wyłącznie po prawej stronie to symbole terminalne.  Generalnie symbole terminalne to symbole z alfabetu definiowanego języka,

Przeniesienie siedziby biblioteki centralnej z ul. Dąbrowskiego w Wirku jest konieczne z powodu złego stanu technicznego dotychcza- sowego budynku, który niszczony