Wyklad CPP 1


Obiektowe programowanie w języku C++
Kurs podstawowy
Dr inż. Lucjan Miękina
upel.agh.edu.pl/wimir/login/
Katedra Robotyki i Mechatroniki
February 28, 2013
1/17
Obiektowe programowanie w języku C++
Pojęcia podstawowe
Literatura:
B. Stroustrup, Język C++, Addison-Wesley, 2000
L. Miękina, Inżynieria oprogramowania, AGH SU 1707
B. Stroustrup, Programming  Principles and Practice Using C++,
Addison-Wesley, 2008.
It is an introduction to programming for people who have never programmed
before. It will also be useful for people who have programmed a bit and want to
improve their style and technique - or simply learn modern C++. It is designed
for classroom use, but written with an eye on self study.
Stroustrup s web page: http://www.research.att.com/ bs/
B. Eckel, Thinking in C++, Prentice Hall, 2002
Literatura dodatkowa:
L. Kuczmański: Język C++
J. Grębosz: Symfonia C++ Standard, Editions 2000, Kraków
2/17
Obiektowe programowanie w języku C++
Pojęcia podstawowe
Język C został uzupełniony o tzw. rozszerzenie obiektowe, umożliwiające i wspierające
programowanie zorientowane obiektowo (OOP). Realizowane to jest przez
wprowadzenie szeregu nowych słów kluczowych i mechanizmów języka.
Rozwój technik programowania:
liniowe - brak procedur i funkcji, wykorzystanie instrukcji skoku warunkowego i
bezwarunkowego jako substytutów strukturalizacji. Realizowane przez język
maszynowy, assembler i wczesne wersje Basic-a
proceduralne - opiera się na przepływie danych przez odpowiednio dobrane
procedury i funkcje, realizujące cząstkowe zadania przetwarzania tych danych.
Obowiązuje schemat: Wybierz procedurę realizującą operację na danych, do
kodowania procedury użyj najlepiej dostosowanego algorytmu. Języki: Fortran,
Algol, Pascal, C, Ada, itd.
modułowe - wymienione wyżej języki proceduralne zawierają wsparcie do
modularnego programowania, które opiera się na wyodrębnieniu części
reprezentacji problemu w postaci modułu, będącego zbiorem metod (funkcji) i
danych, na których te metody operują (stałe, zmienne). Najbardziej istotną nową
cechą podejścia modułowego jest możliwość ukrycia danych modułu przed
nieautoryzowanym dostępem.
3/17
Obiektowe programowanie w języku C++
Pojęcia podstawowe
Rozwój technik programowania - cd.
obiektowe - gdzie położono nacisk na:
tworzenie reprezentacji problemu w postaci zbliżonej do niego samego
łatwą konserwację i rozbudowę oprogramowania
możliwość wielokrotnego użycia modułów programowych (ang. reusability)
lepsze wsparcie dla budowy dużych systemów i pracy grupowej
komponentowe, będące dalszą ewolucją obiektów w kierunku zgodności na
poziomie binarnym, a nie zródłowym. Oznacza to, że tworzy się komponenty
poddane kompilacji i konsolidacji (a więc gotowe do użycia), które zapewniają
jednolity interfejs do usług, których dostarczają.
funkcjonalne -
aspektowe -
4/17
Obiektowe programowanie w języku C++
Cechy obiektowego podejścia do programowania
Niezależnie od języka implementacji, istnieją ogólne zasady obiektowego podejścia do
tworzenia oprogramowania, nazywane modelem obiektowym. Składa się on z
poniższych pojęć:
obiekt  każdy byt (pojęcie lub rzecz), mający znaczenie w dziedzinie
zastosowania
klasa  uogólnienie zbioru obiektów, mających takie same atrybuty, operacje i
znaczenie. Jeśli pewne klasy mają wspólną część, to powinna ona być ich
wspólną klasą bazową (lub inaczej nadklasą).
komunikat (ang. message)  specyfikacja wymiany informacji między obiektami,
zawierająca zlecenie wykonania określonej operacji lub wymiany danych.
abstrakcja proceduralna i abstrakcja danych - polega na ukrywaniu nieistotnych
cech obiektu w trakcie operacji z nim związanych, dzięki temu że obiekt może
być wyposażony w wiedzę o swych operacjach. Dzięki temu ułatwia się operacje i
unika błędów, a także skraca się notację - można lepiej panować nad złożonymi
systemami lub algorytmami.
hermetyzacja (ang. encapsulation) - polega na selektywnym dostępie do
szczegółów obiektu (atrybutów i operacji) i dzięki temu zapewnieniu
niezależności (braku niepotrzebnych sprzężeń). Prywatne atrybuty i operacje są
niedostępne dla otoczenia, stanowiąc elementy wewnętrznego mechanizmu
działania obiektu. Publiczne atrybuty i operacje są dostępne dla otoczenia,
umożliwiając odwoływanie się do obiektu za pomocą komunikatów. Chronione
atrybuty i operacje są dostępne w ciągu podklas danej klasy.
5/17
Obiektowe programowanie w języku C++
Cechy obiektowego podejścia do programowania
dziedziczenie (ang. inheritance) - polega na przejmowaniu cech pewnych
obiektów przez inne, z równoczesnym dodawaniem nowych cech - tworzenie tzw.
specjalizacji. Oznacza to przyporządkowanie atrybutów i operacji do klas zgodnie
z hierarchiczną zależnością, jakiej podlegają klasy. Dzięki temu można budować
systemy złożone, lecz elastyczne w zastosowaniu.
polimorfizm (ang. polymorphism)  polega na nadaniu takiej samej nazwy
różnym atrybutom i operacjom w klasach należących do jednej hierarchii (od
nadklasy przez wszystkie podklasy). Pozwala m.in. na wywołanie tzw. wirtualnej
metody (procedury lub funkcji), która może mieć różne znaczenie w zależności
od kontekstu wywołania.
W oparciu o wymienione zasady modelu obiektowego, powstaje język bardziej zbliżony
do opisywanego problemu (w odróżnieniu od zbliżonego do maszyny). Dzięki tym
założeniom program obiektowo zorganizowany może się składać prawie wyłącznie z
deklaracji zmiennych obiektowych (instancji); w trakcie tych deklaracji wykonywane
są wszystkie operacje inicjalizacji obiektów (definiowania ich stanu początkowego),
tak by mogły one zacząć funkcjonować w otoczeniu innych obiektów. Dalsze
funkcjonowanie każdego obiektu polega na odbiorze komunikatów wysyłanych przez
inne obiekty i odpowiednim ich przetwarzaniu, w ramach którego możliwe jest również
wysyłanie własnych komunikatów, czyli oddziaływanie na otoczenie. Taki model daje
większe możliwości, co jest związane głównie z decentralizacją funkcjonalności (każda
klasa odpowiada za swoją część operacji złożonego systemu) i nie jest potrzebny
żaden nadrzędny mechanizm, który musiałby być odpowiednio bardziej złożony.
6/17
Obiektowe programowanie w języku C++
Typ obiektowy (klasa)
Klasa może być traktowana jako specjalny rodzaj typu strukturowego, składający się z:
pól (jak w strukturze). Pola klasy służą do opisu stanu obiektu, a więc opisują
jego własności. Każdy typ obiektowy jest zwykle opisany unikalnym zbiorem
własności.
metod (będących w istocie funkcjami znanymi z języka C) zadeklarowanych
wewnątrz deklaracji klasy. Metody służą do wykonywania operacji
zdefiniowanych dla typu obiektowego, a więc definiują zachowanie się obiektu.
Metody operują w założeniu na polach dostępnych w klasie i mogą wywoływać
inne metody klasy, a także funkcje zewnętrzne.
UWAGA: W języku C++ struktura może mieć funkcje.
Składnia deklaracji klasy
Deklaracja klasy pierwotnej (czyli nie wywodzącej się z innej, już wcześniej
zdefiniowanej) ma postać:
class Nazwa {
public:
// lista deklaracji pol/metod publicznych
protected:
// lista deklaracji pol/metod chronionych
private:
// lista deklaracji pol/metod prywatnych
};
7/17
Obiektowe programowanie w języku C++
Przykład hierarchii klas
8/17
Obiektowe programowanie w języku C++
Typ obiektowy (klasa)
Nazwa jest nazwą klasy, czyli nowo tworzonego typu obiektowego. Ciało klasy składa
się z dowolnej liczby sekcji, różniących się co do sposobu dostępu do zadeklarowanych
w nich składników. Wyróżnia się sekcje:
prywatne (private). Składniki zdefiniowane w sekcji prywatnej są widoczne jedynie w obrębie
obiektów danej klasy, tzn. można ich używać wewnątrz metod (funkcji) tej klasy. Jeśli
zdefiniowane są pola prywatne, to dla zapewnienia możliwości odczytu ich wartości spoza
klasy można zdefiniować specjalne funkcje dostępu, które mogą być publiczne lub chronione.
Podobne funkcje można zdefiniować dla zapewnienia zmiany wartości wybranych pól
prywatnych.
chronione (protected). Składniki zdefiniowane w sekcji chronionej są widoczne jedynie w
obrębie obiektu danej klasy i klasy pochodnej.
publiczne (public). Składniki zdefiniowane w sekcji publicznej są widoczne wszędzie
(podobnie jak dla struktur). W tej sekcji zwykle muszą być zadeklarowane specjalne funkcje
klasy: konstruktor i destruktor, o ile są przewidziane (jeśli nie są przewidziane, to kompilator
generuje ich domniemane wersje, typowo nie wykonujące żadnych specyficznych operacji).
W ciele klasy może wystąpić dowolna ilość sekcji w dowolnej kolejności.
Reprezentacja obiektów w pamięci
Składniki danej sekcji są umieszczone w pamięci w takiej kolejności jak je
zadeklarowano, natomiast kolejność ułożenia sekcji zależy od kompilatora.
Obiekty mogą być alokowane jako zmienne:
lokalne dynamiczne, tworzone z użyciem new i
usuwane z użyciem delete
modułowe lub globalne
składowe innych obiektów (klas lub tablic)
9/17
Obiektowe programowanie w języku C++
Konstruktor i destruktor
Są to specjalne metody należące do klasy. Konstruktor nosi nazwę taką jak nazwa
klasy (typu obiektowego), a destruktor taką samą, ale poprzedzoną znakiem .
Wywołanie konstruktora ma na celu utworzenie i zainicjowanie obiektu.
Konstruktor jest wywoływany na rzecz pewnego amorficznego (bezpostaciowego)
obszaru pamięci, który jest zamieniany (formatowany) na obiekt.
Wewnątrz konstruktora są dostępne wszystkie składniki klasy (pola i metody).
Klasa może definiować więcej niż 0 konstruktorów (konieczne jest by były to
funkcje przeciążone  o różnej ilości i typie parametrów formalnych) i o
funkcjonalności dostosowanej do potrzeb; każdy z nich może inicjować obiekt tej
samej klasy w inny sposób.
Jeśli nie jest zdefiniowany żaden konstruktor, to automatycznie generuje się
konstruktor domniemany, bezparametrowy.
Klasa może posiadać konstruktor kopiujący, wywoływany z jednym argumentem
typu tej samej klasy.
Wywołanie konstruktora może być jawne (przy dynamicznym tworzeniu obiektu
operatorem new) i niejawne (w miejscu deklaracji zmiennej odpowiedniego typu).
Zadaniem destruktora jest zniszczenie obiektu, czyli przekształcenie tej części
pamięci operacyjnej, którą zajmował obiekt w amorficzny obszar pamięci.
Wywołanie destruktora może być jawne (przy usuwaniu operatorem delete
obiektu utworzonego dynamicznie) i niejawne (w miejscu wyjścia sterowania z
zakresu deklaracji zmiennej odpowiedniego typu).
10/17
Obiektowe programowanie w języku C++
Słowo kluczowe this
Słowo kluczowe this reprezentuje wskaznik do obiektu, którego metoda jest w danej
chwili wykonywana. Jest to zatem wskaznik do bieżącego obiektu, dlatego słowo
kluczowe this może się pojawić tylko w kodzie metod klasy.
Domyślnie, w kodzie dowolnej metody należącej do klasy kompilator traktuje
identyfikator każdej składowej zdefiniowanej w tej klasie (pola lub metody) tak, jak
gdyby był on poprzedzony napisem this-> , czyli był składnikiem klasy.
Wyjątek: jeśli metoda posiada parametr
1 class PierwszaKlasa {
o nazwie identycznej z nazwą pewnego
2 int pole;
3 void Ustaw(int pole) { pola klasy (jak w linii 3), to w kodzie tej
4 this->pole = pole;
metody ta nazwa reprezentuje parametr,
5 };
nie zaś pole. Należy wtedy jawnie użyć
6 public:
wskaznika this przed tym wystąpieniem
7 void Metoda() { Ustaw(1); };
nazwy, które ma oznaczać pole (jak w linii
8 };
4).
Przy wywołaniu dowolnej metody klasy, konieczne jest podanie jej nazwy (z
wymaganymi parametrami wejściowymi w nawiasie okrągłym), a jeśli wywołuje się
metodę z innej klasy niż bieżąca lub na rzecz innego obiektu niż bieżący  przed nazwą
podaje się nazwę obiektu lub wskaznik do niego, np.:
11/17
Obiektowe programowanie w języku C++
Słowo kluczowe this
1 #include "PierwszaKlasa.h"
Skutkiem takiego sposobu wywołania
2
metody jest zainicjowanie wskaznika this
3 int main() {
4 PierwszaKlasa o; // obiekt wartością adresu obiektu o (w linii 7) lub
5 PierwszaKlasa* p = &o; // wskaznik
wartością adresu przechowywanego przez
6 // wywolanie za pomoca obiektu
wskaznik p (w linii 9). Dzieje się to w pro-
7 o.Metoda();
logu każdej metody należącej do klasy, tak
8 // wywolanie za pomoca wskaznika
że metoda zawsze zna aktualną wartość
9 p->Metoda();
this (wie na rzecz którego obiektu działa).
10 }
Możliwe zastosowania wskaznika this:
odczyt adresów obiektów, patrz metoda Info w klasie complex
porównywanie adresów obiektów, patrz metoda Set w klasie complex
odróżnianie identyfikatorów składowych klasy (pól lub metod) od innych
identyfikatorów, patrz pierwszy konstruktor klasy complex.
12/17
Obiektowe programowanie w języku C++
Typ referencyjny
Typ referencyjny
Typem referencyjnym (odniesienia  nie jest to ścisłe określenie, a jedynie próba
dodatkowego objaśnienia) jest taki typ, którego zmienne są synonimami innych
zmiennych. Każde odwołanie do zmiennej typu referencyjnego jest uznawane za
odwołanie do związanej z nią przez referencję innej zmiennej.
Podobnie jak w przypadku zmiennych wskaznikowych, konieczne jest odpowiednie
zainicjowanie zmiennej referencyjnej, tak by było wiadomo z jaką zmienną jest ona
skojarzona (lub inaczej mówiąc  jakiej zmiennej jest synonimem).
Odmiennie od wskazników, w C++ występują wyłącznie stałe referencje. Po
koniecznej inicjalizacji nie mogą już być zmieniane.
Deklaracja zmiennej referencyjnej wymaga użycia symbolu & (ampersand) pomiędzy
nazwą typu bazowego i nazwą zmiennej referencyjnej, na przykład:
int Fix = 12;
int &Ref = Fix; // deklaracja i inicjalizacja zmiennej referencyjnej Ref
Ref = Ref + 1; // ta operacja dotyczy zmiennej Fix !!
Zmienna Ref jest synonimem zmiennej Fix, każda operacja na Ref dotyczy w istocie
zmiennej Fix.
Zastosowanie referencji
Modyfikacja sposobu przekazywania argumentów wywołania do funkcji. Jeśli argument jest
przekazany przez referencję, to funkcja operuje bezpośrednio na tym argumencie, a nie na
jego kopii, jak w standardowym C.
Modyfikacja sposobu zwracania rezultatu wywołania funkcji.
13/17
Obiektowe programowanie w języku C++
Przykład deklaracji klasy
Poniżej zadeklarowano prostą klasę Complex, która opisuje wybrane własności i
operacje zbioru liczb zespolonych.
UWAGA: biblioteki standardowe dostarczane obecnie z kompilatorami C++ zawierają
klasy implementujące pełną funkcjonalność właściwą dla danych typu zespolonego, w
tym również funkcje operatorowe +, -, *, / i inne, które dla tych liczb definiują
wymienione standardowe działania.
1 class Complex {
2 char Name[16];
3 double Re, Im;
4 public:
Typowo klasa jest
5 Complex(); // default ctor (parameter-less)
zadeklarowana w pliku
6 Complex(char* name, double re, double im);
nagłówkowym, natomi-
7 Complex(Complex& c); // copy ctor
ast zdefiniowana w pliku
8 ~Complex(); // destructor
zródłowym.
9 void Set(Complex& c);
10 void SetRe(double re) { this->Re = re; }; Jak widać, niektóre metody
11 void SetIm(double im) { Im = im; };
zostały zarówno zadeklarowane
12 double GetRe(void) { return Re; };
jak i zdefiniowane w tym pliku.
13 double GetIm(void) { return Im; };
Są to tzw. metody otwarte (in-
14 double abs(void);
line), czyli takie, których kod
15 void Info();
będzie umieszczony wszędzie
16 Complex& operator+(const Complex& r);
tam, gdzie następuje ich
17 Complex& operator-(const Complex& r);
wywołanie.
18 Complex& operator*(const Complex& r);
19 Complex& operator=(const Complex& r);
20 bool operator==(const Complex& r);
21 };
14/17
Obiektowe programowanie w języku C++
Plik zródłowy klasy Complex
1 #include
29 // copying field-by-field
2 #include
30 void Complex::Set(Complex& c) {
3 #include
31 if(this == &c)
4 #include "Complex.h"
32 return;
5
33 strcpy(Name, c.Name);
6 // default constructor (parameter-less)
34 Re = c.Re; Im = c.Im;
7 Complex::Complex() {
35 }
8 strcpy(Name, "NN");
36 // evaluating the magnitude
9 Re = 0.; Im = 0.;
37 double Complex::abs(void) {
10 Info(); printf(" created");
38 return sqrt(Re * Re + Im * Im);
11 };
39 }
12 // constructor
40 void Complex::Info() {
13 Complex::Complex(char* name,
41 printf("\n %s: %p, (%5.1f, %5.1f)",
14 double Re, double Im) {
42 Name, this, Re, Im);
15 strcpy(Name, name);
43 }
16 this->Re = Re; this->Im = Im;
17 Info(); printf(" created");
1 #include
18 }
2 #include "Complex.h"
19 // copy constructor
3
20 Complex::Complex(Complex& c) {
4 int main() {
21 strcpy(Name, c.Name);
5 printf("Create objects:");
22 Re = c.Re; Im = c.Im;
6 Complex c;
23 Info(); printf(" created");
7 Complex c2("c2", 10., 20.);
24 }
8 Complex c2bis(c2);
25 // destructor
9 printf("\nDe-allocate");
26 Complex::~Complex(){
10 return 0;
27 Info(); printf(" deleted");
11 }
28 }
15/17
Obiektowe programowanie w języku C++
Prosty przykład programu obiektowego
Program korzysta z klasy Complex, tworząc w sposób niejawny 3 obiekty, a następnie
wyświetlając o nich informacje.
1 #include
2 #include "Complex.h"
3 1 lm@arch> ./a.out
4 int main() { 2 Create objects:
5 printf("Create objects:"); 3 NN: 0x7fff1f2f20d0, (0.0, 0.0) created
6 Complex c; 4 c2: 0x7fff1f2f20f0, (10.0, 20.0) created
7 c.SetRe(1.); 5 c2: 0x7fff1f2f2110, (10.0, 20.0) created
8 c.SetIm(2.); 6 Display info:
9 Complex c2("c2", 10., 20.); 7 NN: 0x7fff1f2f20d0, (1.0, 2.0)
10 Complex c2bis(c2); 8 c2: 0x7fff1f2f20f0, (10.0, 20.0)
11 printf("\nDisplay info:"); 9 c2: 0x7fff1f2f2110, (10.0, 20.0)
12 c.Info(); 10 De-allocate:
13 c2.Info(); 11 c2: 0x7fff1f2f2110, (10.0, 20.0) deleted
14 c2bis.Info(); 12 c2: 0x7fff1f2f20f0, (10.0, 20.0) deleted
15 printf("\nDe-allocate:"); 13 NN: 0x7fff1f2f20d0, (1.0, 2.0) deleted
16 return 0;
17 }
16/17
Obiektowe programowanie w języku C++
Prosty przykład programu obiektowego 2
Program korzysta z klasy Complex, tworząc w sposób jawny (za pomocą operatora
new) 3 obiekty, a następnie wyświetlając o nich informacje. Utworzone obiekty znajdą
się w obszarze sterty. Na koniec obiekty są usuwane za pomocą operatora delete.
1 #include
2 #include "Complex.h"
3
4 int main() {
5 printf("Create objects:");
6 Complex *c = 0, *c2 = 0, *c2bis = 0;
1 lm@arch> ./a.out
7 c = new Complex;
2 Create objects:
8 if(c) {
3 NN: 0x12ed010, (0.0, 0.0) created
9 c->SetRe(1.);
4 c2: 0x12ed040, (10.0, 20.0) created
10 c->SetIm(2.);
5 c2: 0x12ed070, (10.0, 20.0) created
11 }
6 Display info:
12 c2 = new Complex("c2", 10., 20.);
7 NN: 0x12ed010, (1.0, 2.0)
13 if(c2)
8 c2: 0x12ed040, (10.0, 20.0)
14 c2bis = new Complex(*c2);
9 c2: 0x12ed070, (10.0, 20.0)
15 printf("\nDisplay info:");
10 De-allocate:
16 if(c) c->Info();
11 NN: 0x12ed010, (1.0, 2.0) deleted
17 if(c2) c2->Info();
12 c2: 0x12ed040, (10.0, 20.0) deleted
18 if(c2bis) c2bis->Info();
13 c2: 0x12ed070, (10.0, 20.0) deleted
19 printf("\nDe-allocate:");
20 if(c) delete c;
21 if(c2) delete c2;
22 if(c2bis) delete c2bis;
23 return 0;
24 }
17/17


Wyszukiwarka

Podobne podstrony:
Wyklad CPP 6
Wyklad CPP 2
Wyklad CPP 7
Wyklad CPP 3
Wyklad CPP 5
CPP WYKLAD 1
CPP WYKLAD 7
CPP WYKLAD 6
CPP WYKLADY ANALIZA 2
CPP WYKLAD 1 2
CPP WYKLAD 3
CPP WYKLAD 4 5
CPP WYKLADY ANALIZA 1
Sieci komputerowe wyklady dr Furtak
Wykład 05 Opadanie i fluidyzacja

więcej podobnych podstron