Zaawansowane programowanie w C++ (PCP) Wykład 1 - sprawy organizacyjne i wprowadzenie. dr inż. Robert Nowak - p. 1/27
Cel i zakres przedmiotu Umiejętność programowania to umiejętność rozwiazania problemów przy pomocy komputera. Czy ten problem może być rozwiazany przy pomocy komputera? Czy ten problem powinien być rozwiazany przy pomocy komputera? Komputer = głupi automat. zapoznanie słuchaczy z zagadnieniami tworzenia oprogramowania w C++ współcześnie stosowane techniki i biblioteki Zakładana jest znajomość programowania strukturalnego i obiektowego oraz praktyczna znajomość języka C++. - p. 2/27
Podstawowe dane o przedmiocie» Podstawowe dane o przedmiocie» Zajęcia» Literatura» Zaliczenie przedmiotu» Wymaganie oprogramowanie Miejsce spotkań: Piatki 8 15 10 00, sala N7 (wykład) Piatki 8 15 10 00, sala N102 (laboratorium) Prowadzacy: dr inż. Robert Nowak, Zakład Sztucznej Inteligencji, Wydział Elektroniki i Technik Informacyjnych, Politechnika Warszawska. e-mail: r.m.nowak@elka.pw.edu.pl strona przedmiotu: http://staff.elka.pw.edu.pl/ rnowak2/pcp2007l - p. 3/27
Zajęcia» Podstawowe dane o przedmiocie» Zajęcia» Literatura» Zaliczenie przedmiotu» Wymaganie oprogramowanie 1 Klasy autonomiczne, cykl życia obiektów. 2 Agregacja i dziedziczenie, polimorfizm, klasy abstrakcyjne. 3 Laboratorium 1: funkcje wirtualne, hierarchia klas. 4 Wzorce projektowe. 5 Obsługa błędów, mechanizm wyjatków, sprytne wskaźniki. 6 Laboratorium 2: wyjatki. Rozdanie zadań projektowych. 7 Rola projektowania i testowania, repozytorium. 8 Szablony, wstęp do biblioteki standardowej, strumienie. 9 Biblioteka standardowa: kontenery, algorytmy. 10 Laboratorium 4: Kolokwium. 11 Laboratorium 5: realizacja projektu 12 Laboratorium 6: realizacja projektu 13 Aplikacje wielowatkowe, synchronizacja, boost::thread. 14 Laboratorium 7: aplikacje wielowatkowe. - p. 4/27
Literatura» Podstawowe dane o przedmiocie» Zajęcia» Literatura» Zaliczenie przedmiotu» Wymaganie oprogramowanie Bjarne Stroustrup, Język C++, WNT 2002. Bruce Eckel, Thinking in C++, Helion 2002. E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Wzorce projektowe, WNT, 2005. A. Alexandrescu, Nowoczesne projektowanie w C++, WNT, 2005. A. Alexandrescu and H. Sutter, Jȩzyk C++. Standardy kodowania. 101 zasad, wytycznych i zalecanych praktyk, Helion, 2005. B. Karlsson, Wiȩcej niż C++. Wprowadzenie do bibliotek Boost, Helion, 2006. S. Meyers, 50 efektywnych sposobów na udoskonalenie Twoich programów, Helion, 2003. - p. 5/27
Zaliczenie przedmiotu» Podstawowe dane o przedmiocie» Zajęcia» Literatura» Zaliczenie przedmiotu» Wymaganie oprogramowanie kolokwium 0 30pkt Podział punktów: ćwiczeń laboratoryjnych 0 40pkt projektów 0 30pkt Warunkiem zaliczenia jest uzyskanie przynajmniej 51 pkt. Ocena: 91 100 punktów ocena 5 81 90 pkt. ocena 4 2 1 71 80 pkt. ocena 4 61 70 pkt. ocena 3 2 1 51 60 pkt. ocena 3 0 50 pkt. ocena 2 - p. 6/27
Wymaganie oprogramowanie» Podstawowe dane o przedmiocie» Zajęcia» Literatura» Zaliczenie przedmiotu» Wymaganie oprogramowanie kompilatory: the GNU Compiler Collection Microsoft Visual Studio 2005 biblioteki: stl boost - http://www.boost.org inne: repozytorium - http://subversion.tigris.org edytor tekstu debugger - p. 7/27
Sposób, aby zostać dobrym programista» Sposób, aby zostać dobrym programista» zasady dobrego stylu programowania Czytać kod innych. Myśleć! Programować. - p. 8/27
zasady» Sposób, aby zostać dobrym programista» zasady dobrego stylu programowania Wykrywanie błędów w programach: Wykorzystywać kompilator. Zawsze doprowadzić do czystej kompilacji (bez żadnych ostrzeżeń) na najwyższym poziomie. Rozumieć każde ostrzeżenie. Stosować standardy kodowania: pliki źródłowe, nazewnictwo, formatowanie kodu źródłowego, stosować konsekwentnie ten sam styl kodowania. - p. 9/27
Typy wbudowane» Typy wbudowane» Czas życia obiektów» Wykorzystywanie stałych» Konwersja typów» Instrukcje sterujace» Przeciażanie nazw funkcji» Przeciażanie nazw (przykład)» Argumenty domyślne» Preprocesor» Wykorzystanie biblioteki standardowej C» Projektowanie modułów, rola testowania logiczny: bool, true, false całkowite: int, long,... rzeczywiste: double,... znakowe: char, wchar_t typ wyliczeniowy enum Kolory { RED = 1, GREEN = 2, BLUE = 4}; void - oznacza brak informacji typy wskaźnikowe typy tablicowe typy referencyjne typedef - p. 10/27
Czas życia obiektów» Typy wbudowane» Czas życia obiektów» Wykorzystywanie stałych» Konwersja typów» Instrukcje sterujace» Przeciażanie nazw funkcji» Przeciażanie nazw (przykład)» Argumenty domyślne» Preprocesor» Wykorzystanie biblioteki standardowej C» Projektowanie modułów, rola testowania l-wartość: odnosi się do czegoś co istnieje w pamięci. Automatyczne: tworzone w chwili napotkania definicji sa niszczone w momencie wyjścia z zasięgu (np. z bloku) definicja powinna być wtedy gdy można zainicjować Statyczne (globalne i zadeklarowane jako static) tworzone tylko raz sa niszczone po zakończeniu programu dynamiczne (tworzone na stercie) operatory new i delete (uwaga! oddzielna wersja dla tablic), programista steruje czasem życia obiektów (tworzy je i usuwa), Nie używamy funkcji z <stdlib.h>, czyli malloc, free itp. - p. 11/27
Wykorzystywanie stałych» Typy wbudowane» Czas życia obiektów» Wykorzystywanie stałych» Konwersja typów» Instrukcje sterujace» Przeciażanie nazw funkcji» Przeciażanie nazw (przykład)» Argumenty domyślne» Preprocesor» Wykorzystanie biblioteki standardowej C» Projektowanie modułów, rola testowania Stałe definiuje się za pomoca słowa kluczowego const. const int NUM = 34; const int WZROST[] = { 174, 185, 193, 168 }; unika się magicznych liczb w kodzie, pokazuje się, że funkcja nie zmienia argumentów, pozwala się kompilatorowi na optymalizacje. Systematycznie korzystać ze stałych symbolicznych! int i = 2, j = 3; const int* p = &i; p = &j; *p = 4; int* const q = &i; q = &j; *q = 4; - p. 12/27
Konwersja typów» Typy wbudowane» Czas życia obiektów» Wykorzystywanie stałych» Konwersja typów» Instrukcje sterujace» Przeciażanie nazw funkcji» Przeciażanie nazw (przykład)» Argumenty domyślne» Preprocesor» Wykorzystanie biblioteki standardowej C» Projektowanie modułów, rola testowania Nie używa się rzutowania w stylu C! nie używa się void* unikać konwersji typów Operatory rzutowania: static_cast - umożliwia konwersję pomiędzy spokrewnionymi typami const_cast - znosi kwalifikator const reinterpret_cast - dowolna konwersja (tak jak w C) dynamic_cast - rzutowanie w górę hierarchii klas double d = 3.2; int i = static_cast<int>(d); - p. 13/27
Instrukcje sterujace» Typy wbudowane» Czas życia obiektów» Wykorzystywanie stałych» Konwersja typów» Instrukcje sterujace» Przeciażanie nazw funkcji» Przeciażanie nazw (przykład)» Argumenty domyślne» Preprocesor» Wykorzystanie biblioteki standardowej C» Projektowanie modułów, rola testowania Instrukcje warunkowe: if... else... switch Iteracja: for while do... while Wołanie funkcji, rekurencja. - p. 14/27
Przeciażanie nazw funkcji» Typy wbudowane» Czas życia obiektów» Wykorzystywanie stałych» Konwersja typów» Instrukcje sterujace» Przeciażanie nazw funkcji» Przeciażanie nazw (przykład)» Argumenty domyślne» Preprocesor» Wykorzystanie biblioteki standardowej C» Projektowanie modułów, rola testowania Funkcje moga mieć te same nazwy. bada się zgodność typów parametrów formalnych i aktualnych, znajdowania właściwej wersji funkcji: 1. ścisła zgodność; 2. promowanie w zakresie typów całkowitych(np. bool int ); 3. standardowe konwersje (np. int double); 4. konwersje zdefiniowane przez użytkownika, 5. wielokropek w deklaracji funkcji (wiele argumentów). Jeżeli znajdzie się dwie pasujace deklaracje: zgłaszany jest bład kompilacji. - p. 15/27
Przeciażanie nazw (przykład)» Typy wbudowane» Czas życia obiektów» Wykorzystywanie stałych» Konwersja typów» Instrukcje sterujace» Przeciażanie nazw funkcji» Przeciażanie nazw (przykład)» Argumenty domyślne» Preprocesor» Wykorzystanie biblioteki standardowej C» Projektowanie modułów, rola testowania Przykład: void print(double); void print(long); print(1l);////print(long) print(1.0);////print(double) print(1);////błąd - niezgodność nie można przeciażać ze względu na zwracana wartość; jest to ułatwienie notacyjne (to programista decyduje, że funkcje o tych samych nazwach wykonuja podobne operacje); stosowane np. dla różnych konstruktorów. ręczne usuwanie niejednoznaczności: jawna konwersja typu, np. static_cast. - p. 16/27
Argumenty domyślne» Typy wbudowane» Czas życia obiektów» Wykorzystywanie stałych» Konwersja typów» Instrukcje sterujace» Przeciażanie nazw funkcji» Przeciażanie nazw (przykład)» Argumenty domyślne» Preprocesor» Wykorzystanie biblioteki standardowej C» Projektowanie modułów, rola testowania Wartość wstawiana, gdy nie dostarczono argumentu. class Point { public: Point(int x = 0, int y = 0); private: int x_; int y_; }; Point::Point(int x, int y) //Nie powtarzać arg. domyślnych : x_(x), y_(y) { } Point p, r(1), s(1,2); Przeciażanie - gdy różny kod. Argumenty domyślne - gdy wiele argumentów, a niektóre maja typowe wartości. Domyślne moga być tylko końcowe argumenty. - p. 17/27
Preprocesor» Typy wbudowane» Czas życia obiektów» Wykorzystywanie stałych» Konwersja typów» Instrukcje sterujace» Przeciażanie nazw funkcji» Przeciażanie nazw (przykład)» Argumenty domyślne» Preprocesor» Wykorzystanie biblioteki standardowej C» Projektowanie modułów, rola testowania Preprocesora należy używać do: dołaczania plików nagłówkowych; #include <nazwa> #include nazwa zabezpieczania plików nagłówkowych przed wielokrotnym dołaczaniem; kompilacji warunkowej. I do niczego więcej! - p. 18/27
Wykorzystanie biblioteki standardowej C» Typy wbudowane» Czas życia obiektów» Wykorzystywanie stałych» Konwersja typów» Instrukcje sterujace» Przeciażanie nazw funkcji» Przeciażanie nazw (przykład)» Argumenty domyślne» Preprocesor» Wykorzystanie biblioteki standardowej C» Projektowanie modułów, rola testowania Wszystkie nagłówki z C zostały obudowane, aby można było je wykorzystywać w C++. Zmieniono ich nazwy. <cassert> - asercje (niezmienniki); <cctype> - klasyfikacja znaków (isalpha, isspace,... ); <cfloat> - ograniczenia reprezentacji zmiennopozycyjnej (np. DBL_MAX); <climits> - stałe ograniczajace zakresy typów wbudowanych (np. INT_MAX); <cmath> - funkcje matematyczne. - p. 19/27
Projektowanie modułów, rola testowania» Typy wbudowane» Czas życia obiektów» Wykorzystywanie stałych» Konwersja typów» Instrukcje sterujace» Przeciażanie nazw funkcji» Przeciażanie nazw (przykład)» Argumenty domyślne» Preprocesor» Wykorzystanie biblioteki standardowej C» Projektowanie modułów, rola testowania Moduł zawiera interfejs (nagłówek) oraz implementację. Używaj przestrzni nazw (jedna przestrzeń nazw na bibliotekę - zbiór powiazanych modułów). Każdy moduł powinien mieć swój test. Test powinien wykonywać się automatycznie (nie powinien komunikować się z człowiekiem). Wykorzystywać asercje do testowania. - p. 20/27
Programowanie obiektowe Wszystkie byty w programie sa obiektami. Program to zbiór obiektów, które się ze soba komunikuja. każdy obiekt posiada typ i tożsamość.» Programowanie obiektowe» Funkcje składowe (metody)» Konstruktor» Destruktor» Konstrukcja i destrukcja» Tworzenie kopii obiektu» Konstruktor kopiujacy Możliwość definiowania typów przez użytkownika: struct class struct X {private:... to to samo co class X {..., ale konwencje... - p. 21/27
Funkcje składowe (metody)» Programowanie obiektowe» Funkcje składowe (metody)» Konstruktor» Destruktor» Konstrukcja i destrukcja» Tworzenie kopii obiektu» Konstruktor kopiujacy dostęp do składowych niejawny argument - wskaźnik this odwołania do this można pominać (skrócenie zapisu) metody stałe metody inline Sekcje (kontrola dostępu) - dziela klasę na interfejs i implementację. class Prostokat { public: Prostokat(const Punkt& a, const Punkt& b); private: Punkt leftup; Punkt rightdown; }; - p. 22/27
Konstruktor» Programowanie obiektowe» Funkcje składowe (metody)» Konstruktor» Destruktor» Konstrukcja i destrukcja» Tworzenie kopii obiektu» Konstruktor kopiujacy Specjalna metoda, która jest wołana, gdy jest tworzony obiekt danej klasy. zawsze wołany - programista nie zapomni zainicjować składowych, możliwość inicjacji prywatnych składowych, elegancki zapis inicjacji obiektów. struct Punkt { int x; int y; //konstruktor domyślny Punkt() { x = 0; y = 0; } //konstruktor Punkt(int wx, int wy) { x = wx; y = wy; } }; Punkt p; //Tworzy punkt, wywołuje konstruktor domyślny Punkt r(1,2); //Tworzy punkt o współrzędnych x == 1, y == 2 - p. 23/27 Punkt* pr = new Punkt(1,2); //To samo, ale obiekt na stercie
Destruktor Jeżeli obiekt klasy ma przydzielane zasoby, to powinno się je zwalniać. Destruktor - metoda wołana gdy niszczony jest obiekt.» Programowanie obiektowe» Funkcje składowe (metody)» Konstruktor» Destruktor» Konstrukcja i destrukcja» Tworzenie kopii obiektu» Konstruktor kopiujacy class PunktN { public: PunktN(int n) { wsp = new int[n]; for(int i=0;i<n;++i) wsp[i] = 0; } PunktN() { delete wsp; } private: int* wsp; }; - p. 24/27
Konstrukcja i destrukcja» Programowanie obiektowe» Funkcje składowe (metody)» Konstruktor» Destruktor» Konstrukcja i destrukcja» Tworzenie kopii obiektu» Konstruktor kopiujacy obiekt automatyczny (nazwany) tworzenie deklaracja (za każdym razem) usuwanie opuszcza się blok obiekt na stercie operator new operator delete (niesta- składowa tyczna) lokalny obiekt statyczny obiekt globalny, składowa statyczna obiekt tymczasowy tworzenie obiektu nadrzędnego deklaracja (za pierwszym razem!) poczatek programu podczas wartościowania wyrażenia niszczenie obiektu nadrzędnego koniec programu koniec programu po dojściu do końca wyrażenia - p. 25/27
Tworzenie kopii obiektu» Programowanie obiektowe» Funkcje składowe (metody)» Konstruktor» Destruktor» Konstrukcja i destrukcja» Tworzenie kopii obiektu» Konstruktor kopiujacy Tworzenie kopii: jawne Foo a; Foo b(a); jawne Foo c = a; przekazywanie wyniku przez wartość; Foo get(); Foo d = get(); przekazywanie argumentu przez wartość; void put(foo x); put(a); class Foo { public: //Deklaracja konstruktora kopiującego Foo(const Foo&);... }; - p. 26/27
Konstruktor kopiujacy Jeżeli brak definicji konstruktora kopiujacego, to zostanie on wygenerowany Obiekt może być przekazywany przez wartość, gdy konstruktor kopiujacy będzie prywatny.» Programowanie obiektowe» Funkcje składowe (metody)» Konstruktor» Destruktor» Konstrukcja i destrukcja» Tworzenie kopii obiektu» Konstruktor kopiujacy Zawsze definiować (dla klas autonomicznych): konstruktor (lub konstruktory) konstruktor kopiujacy destruktor operator przypisania (operator=) - p. 27/27