Języki programowania, wtorek , 12:15-13:45 Zadanie 11 - ostatnie

Podobne dokumenty
PARADYGMATY PROGRAMOWANIA Wykład 4

C++ Przeładowanie operatorów i wzorce w klasach

Szablony funkcji i klas (templates)

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Programowanie w C++ Wykład 8. Katarzyna Grzelak. 15 kwietnia K.Grzelak (Wykład 8) Programowanie w C++ 1 / 33

Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1

Programowanie w C++ Wykład 9. Katarzyna Grzelak. 14 maja K.Grzelak (Wykład 9) Programowanie w C++ 1 / 30

Wykład 4: Klasy i Metody

Programowanie w C++ Wykład 6. Katarzyna Grzelak. 1 kwietnia K.Grzelak (Wykład 6) Programowanie w C++ 1 / 43

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) {

Szablony klas, zastosowanie szablonów w programach

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) { zdefiniuje. Integer::operator=(ri);

Programowanie w C++ Wykład 11. Katarzyna Grzelak. 13 maja K.Grzelak (Wykład 11) Programowanie w C++ 1 / 30

Programowanie w C++ Wykład 12. Katarzyna Grzelak. 28 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 27

Programowanie w C++ Wykład 7. Katarzyna Grzelak. 23 kwietnia K.Grzelak (Wykład 7) Programowanie w C++ 1 / 40

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta Strona 1 z 26. Powrót. Full Screen. Zamknij.

Języki i techniki programowania Ćwiczenia 2

Część 4 życie programu

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Kompilacja javac prog.java powoduje wyprodukowanie kilku plików o rozszerzeniu.class, m.in. Main.class wykonanie: java Main

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) {

2. Klasy cz. 2 - Konstruktor kopiujący. Pola tworzone statycznie i dynamicznie - Funkcje zaprzyjaźnione - Składowe statyczne

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec

Programowanie w języku C++

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Klasa jest nowym typem danych zdefiniowanym przez użytkownika. Najprostsza klasa jest po prostu strukturą, np

Języki i techniki programowania Ćwiczenia 4 Wzorce

Dokumentacja do API Javy.

Wprowadzenie do języka Java

Język C++ wykład VIII

1 Podstawy c++ w pigułce.

Programowanie obiektowe, wykład nr 6. Klasy i obiekty

1 Podstawy c++ w pigułce.

Zaawansowane programowanie w języku C++ Funkcje uogólnione - wzorce

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 26 marca kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 40

Szablony. Szablony funkcji

Programowanie współbieżne Wykład 8 Podstawy programowania obiektowego. Iwona Kochaoska

Algorytmy i złożoności. Wykład 3. Listy jednokierunkowe

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Wykład 9: Polimorfizm i klasy wirtualne

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

Podstawy Programowania Obiektowego

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania

Lab 9 Podstawy Programowania

TEMAT : KLASY DZIEDZICZENIE

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy :

Programowanie w Javie 1 Wykład i Ćwiczenia 2 Przegląd podstawowych klas w Javie (elementy programowania obiektowego) Płock, 16 października 2013 r.

Algorytmy i język C++

PROE wykład 2 operacje na wskaźnikach. dr inż. Jacek Naruniec

Podstawy programowania skrót z wykładów:

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 4. Karol Tarnowski A-1 p.

Definiowanie własnych klas

Programowanie obiektowe, wykład nr 7. Przegląd typów strukturalnych - klasy i obiekty - c.d.

Konwersje napis <-> liczba Struktury, unie Scanf / printf Wskaźniki

Wykład 8: klasy cz. 4

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Zajęcia nr 5 Algorytmy i wskaźniki. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

Przypomnienie o klasach i obiektach

Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.

Laboratorium 5: Tablice. Wyszukiwanie binarne

Programowanie obiektowe

Metody Metody, parametry, zwracanie wartości

Języki Programowania. Prowadząca: dr inż. Hanna Zbroszczyk. tel: Konsultacje: piątek:

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

Programowanie obiektowe. Wykład 5. C++: szablony

Typy wyliczeniowe Konwersje napis <-> liczba Struktury, unie Scanf / printf Wskaźniki

> C++ dynamiczna alokacja/rezerwacja/przydział pamięci. Dane: Iwona Polak. Uniwersytet Śląski Instytut Informatyki

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Technologie i usługi internetowe cz. 2

Rozdział 4 KLASY, OBIEKTY, METODY

Wykład 1. Program przedmiotu. Programowanie Obiektowe (język C++) Literatura. Program przedmiotu c.d.:

Podstawy programowania. Wykład 7 Tablice wielowymiarowe, SOA, AOS, itp. Krzysztof Banaś Podstawy programowania 1

Języki i techniki programowania Ćwiczenia 3 Dziedziczenie

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Wykład 5: Klasy cz. 3

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji.

PARADYGMATY PROGRAMOWANIA Wykład 3

Instrukcja do pracowni specjalistycznej z przedmiotu. Obiektowe programowanie aplikacji

Różne właściwości. Różne właściwości. Różne właściwości. C++ - klasy. C++ - klasy C++ - KLASY

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 16 kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 27

Szablony funkcji i szablony klas

Programowanie obiektowe. Dr hab. Inż. Marta Gładysiewicz-Kudrawiec Pokój 229 A1 Operatory new delete pliki-odczyt

Paradygmaty programowania. Paradygmaty programowania

Programowanie komputerowe. Zajęcia 1

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy WSKAŹNIKI KLASOWE

Wstęp do programowania

Wskaźniki. nie są konieczne, ale dają językowi siłę i elastyczność są języki w których nie używa się wskaźników typ wskaźnikowy typ pochodny:

Podstawy programowania w języku C++ Zadania - dziedziczenie i polimorfizm

Wykład 1. Program przedmiotu. Programowanie (język C++) Literatura. Program przedmiotu c.d.:

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu.

Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady

Programowanie obiektowe W3

Algorytmy i Struktury Danych.

Transkrypt:

Języki programowania, wtorek 10.01.2017, 12:15-13:45 Zadanie 11 - ostatnie Dzisiaj wykorzystamy kolejną bardzo ważną rzecz języka C++ - szablony funkcji i szablony klas. Wstęp co to są klasy i funkcje szablonowe w języku C++? Rozważmy prostą klasę, która przechowuje jakiś typ informacji, na przykład tablicę int'ów: class KlasaInt int *tablica int rozmiar; public: KlasaInt(int Rozmiar); void UstawElement(int poz, int wartosc); int PobierzElement(int poz); ; KlasaInt::KlasaInt(int Rozmiar) rozmiar = Rozmiar; tablica = new int[rozmiar]; void KlasaInt::UstawElement(int poz, int wartosc) tablica[poz]=wartosc; int KlasaInt::PobierzElement(int poz) return tablica[poz]; int main() KlasaInt kl(10); kl.ustawelement(5) = 20; cout<<kl.pobierzelement(5)<<endl; return 0; Co by należało zrobić, gdybyśmy potrzebowali przechować w identyczny sposób dodatkowo inne typy danych. np. double, std::string, char*, etc.? Musielibyśmy za każdym razem, dla każdego oddzielnego typu danych, który jest nam potrzebny, tworzyć nową klasę (np. KlasaString, gdzie mielibyśmy string *tablica zamiast int *tablica itp.). Napisanie sporej ilości tego typu klas zajęłoby nam pewną ilość czasu oraz zwiększyło znacznie ilość plików w projekcie (można sobie wyobrazić duży projekt, gdzie każdy dodaje klasy różniące się właściwie tylko typem przechowywanych danych a służących do tych samych celów ogrom klas!). Na szczęście język C++ przychodzi nam tu z rozwiązaniem takiego problemu i pozwala tworzyć klasy szablonowe (ang. template class), które dostosowują się automatycznie do typu danych używanego w programie głównym. Przykład klasy szablonowej analogicznej do przykładu powyżej jest następujący: class KlasaSzablonowa T *tablica int rozmiar; public: KlasaSzablonowa(int Rozmiar); void UstawElement(int poz, T wartosc); T PobierzElement(int poz); ; KlasaSzablonowa<T>::KlasaSzablonowa(int Rozmiar) rozmiar = Rozmiar; tablica = new T[Rozmiar]; 1

void KlasaInt<T>::UstawElement(int poz, T wartosc) tablica[poz]=wartosc; T KlasaInt<T>::PobierzElement(int poz) return tablica[poz]; int main() KlasaSzablonowa<int> klint(10); klint.ustawelement(5) = 20; cout<<klint.pobierzelement(5)<<endl; KlasaSzablonowa<string> klstring(10); klstring.ustawelement(5) = "tekst"; cout<<klstring.pobierzelement(5)<<endl; return 0; Załóżmy teraz, że w naszej klasie szablonowej mamy również metodę Dodaj, która zwraca sumę elementów dwóch obiektów z wybranych pól tablicy tablica, czyli: T KlasaSzablonowa<T>::Dodaj(int poz1, int poz2) T obiekt = tablica[poz1]+tablica[poz2]; return obiekt; Taka metoda zadziała dla prostych typów danych, np. int, double, string, itp. (czyli takich, gdzie mamy zdefiniowany operator + i takie działanie ma sens). Co by się jednak stało, gdyby nasza klasa przechowywała na przykład napisane wcześniej obiekty klasy Histogram?(czyli coś bardziej skomplikowanego)? Taka metoda oczywiście nam nie zadziała dla histogramu (nie zdefiniowaliśmy przeciążonego operatora + dla klasy Histogram i jego użycie wyrzuciłoby nam błąd). Nic nie szkodzi! Język C++ przynosi nam i tutaj rozwiązanie można tworzyć specjalizowane metody w klasach szablonowych, oto przykład metody Dodaj dla histogramów: template<> Histogram KlasaSzablonowa<Histogram>::Dodaj(int poz1, int poz2) Histogram c = tablica[poz1]; for(int i=0;i<c->iloscbinow()) c.ustawliczbezliczen(i,tablica[poz1]->pobierzliczbezliczen(i) +tablica[poz]->pobierzliczbezliczen(i)); return c; //to tylko przykład - tu robimy cokolwiek z obiektami typu Histogram, np. tworzymy wyjsciowy histogram gdzie w kazdym binie liczba zliczen jest suma z histogramow tablica[poz1] i tablica[poz2] W naszej klasie możemy mieć wiele specjalizowanych metod (również wiele specjalizowanych metod o tej samej nazwie dla różnych obiektów). Kompilator w trakcie kompilowania programu sam zdecyduje, którą metodę ma użyć (w przypadku wszystkich typów obiektów użyje metody ogólnej Dodaj z operatorem +, ale jeśli nasza klasa będzie akurat przechowywać histogramy, to automatycznie użyje metody specjalizowanej dla klasy Histogram). Uwaga! W przypadku klas szablonowych wszystko (zarówno definicję klasy jak i metody klasy) piszemy tylko w pliku.h (czyli najczęściej dla jednej klasy jeden plik.h) nie możemy pisać definicji metod w pliku.cpp! W języku C++ oprócz klas szablonowych możemy również tworzyć funkcje szablonowe. Np. załóżmy, że mamy kilka klas, które mają taką samą metodę (dajmy na to int GetRozmiar()). Chcielibyśmy stworzyć funkcję, która porównuje rozmiar dwóch obiektów dowolnej z tych klas i zwraca większą wartość. Nic trudnego, możemy dostawić więcej typów danych: template<class T1, class T2> int CompareRozmiar(T1 obiekt1, T2 obiekt2) 2

if(obiekt1.getrozmiar()>obiekt2.getrozmiar()) return obiekt1.getrozmiar(); else return obiekt2.getrozmiar(); Oczywiście możemy dodawać więcej typów klas w nagłówku template, możemy je też dowolnie nazywać (np. template<class A, class B, class C, class D> itp.). Zadanie do wykonania Część I W naszym zadaniu wykorzystamy napisaną wcześniej klasę Histogram tworzącą listę. Klasę tą napisaliśmy tak, by mogła przechowywać jedynie dane typu int. Teraz natomiast, zamiast pisać dwie lub więcej klas, chcemy nasz histogram uogólnić, by mógł przyjmował elementy dowolnego typu (np. wynikiem dzielenia dwóch histogramów przez siebie może być histogram z niecałkowitą liczbą zliczeń w binach). Jak to zrobić? Musimy go przerobić właśnie na klasę szablonową. Na koniec, aby przećwiczyć dziedziczenie i abstrakcyjne typy danych (ATD), należy również stworzyć abstrakcyjną klasę bazową THistogram dla klasy szablonowej Histogram. 2 p. Część II Chcemy rozszerzyć jej działanie napisanej na wcześniejszych zajęciach klasy List na elementy dowolnego typu. Zasada działania naszej klasy z punktu widzenia programu będzie praktycznie identyczna jak listy ze standardowej biblioteki szablonów STL, np.: List<double> *mylist = new List<double>(); //tworzy liste przechowujaca typ double za pomoca naszej klasy List list<double> *myliststl = new list<double>(); //tworzy liste przechowujaca typ double za pomoca klasy z biblioteki STL Do wykonania: przerobienie klasy List tak, by stała się klasą szablonową. Stworzenie w programie listy przy użyciu naszej klasy oraz listy z biblioteki STL na zmiennych typu double, dodanie do list 3 elementów, wypisanie obu list. Przy tworzeniu klasy List stworzyliśmy pomocniczą klasę Element chcemy, aby klasa Element była zadeklarowana wewnątrz klasy List (klasa w klasie). 2 p. Uwaga! Należy posiadać poprawnie działającą wersję klasy List oraz poprawnie działającą klasę z histogramem Histogram. Klasy szablonowe piszemy tylko w plikach.h nie tworzymy pliku.cpp (ponieważ klasa szablonowa jest kompilowana dopiero przy jej użyciu w trakcie wykonywania programu). Używamy pliku Makefile w najbardziej zaawansowanej postaci. Przydatne linki: http://cpp0x.pl/kursy/kurs-c++/szablony-klas/317 http://4programmers.net/c/szablony_klas 3

Część III do skończenia i przećwiczenia w domu 1 p. Wyszukiwanie ścieżki w grafie. Macierz sąsiedztwa. Algorytm Djikstry. Czytanie pseudokodu. W teorii grafów macierz sąsiedztwa grafu G jest kwadratową macierzą w której a ij oznacza wagę krawędzi pomiędzy wierzchołkami i i j. Dla przykładu graf z 7 wierzchołkami: 0 1 0 0 2 0 0 1 0 5 0 1 0 0 0 5 0 3 0 0 0 A = 0 0 3 0 0 2 0 2 1 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 1. Należy stworzyć klasę graf używając dwuwymiarowej tablicy (macierz sąsiedztwa) do przechowywania informacji o jej krawędziach. Klasa powinna mieć następujące metody: Graf(int max) konstruktor ; max maksymalna ilość wierzchołków w danym grafie. W przypadku osiągnięcia tej liczby dodanie nowego wierzchołka nie będzie możliwe. void init() - zeruje wszystkie pola macierzy sąsiedztwa void add() - dodanie wierzchołka void remove(int r) - usunięcie wierzchołka o numerze r void display() - wyświetlenie grafu (macierzy sąsiedztwa) void add_edge(int n, int m, int w=1)- dodanie krawędzi pomiędzy wierzchołkami o numerach m i n (oraz wagą w) void remove_edge() - usunięcie krawędzi (dwa numery wierzchołków powinny być wprowadzane z klawiatury po wywołaniu metody) oraz destruktor. W funkcji main stworzyć graf odpowiadający podanemu powyżej w przykładzie. Macierz sąsiedztwa powinna być zaimplementowana jako dwuwymiarowa tablica z dynamicznie alokowaną pamięcią. 2. Należy zaimplementować algorytm Djikstry do wyszukiwania najkrótszej ścieżki w grafie jako metodę klasy graf na podstawie podanego na następnej stronie pesudokodu. void dijkstra(int source, int target) - wyszukiwanie najkrótszej ścieżki od source do target Oraz przetestować go dla stworzonego wcześniej grafu, oraz ścieżek: (1,3), (6,7), (6, 5). 3. Rozszerzyć klasę graf w ten sposób, by maksymalna liczba wierzchołków w grafie zmieniała się, jeśli będziemy chcieli dodać kolejny wierzchołek, przekraczający tę liczbę (odpowiednie zwalnianie i alokacja pamięci!). function Dijkstra(Graph, source, target): //deklarujemy wszystkie tablice for each vertex v in Graph: // Inicjalizacje, dla każdego wierzchołka. distance[v] := infinity ; // Odległość od source do v (nieznana, zakładamy nieskończoność) previous[v] := -1 ; // Tablica zapisująca wierzchołki na najkrótszej ścieżce VISITED[v] := 0; // Żaden z wierzchołków nie był odwiedzony. Np. jeśli end for ; wierzchołek i odwiedzony: VISITED[i]=1. distance[source] := 0 ; //Odległość od punktu poczatkowego = 0 if source = target // Jeśli source jest równe target ten sam wierzchołek print "The same vertex" exit //Zakończyć działanie programu int tmp := infinity; //nieskończoność to np. 999999999 int visited_nodes := 0; //licznik odwiedzonych wierzchołków int current = source; //current = obecny. Startujemy od wierzchołka początkowego source while visited_nodes < Graph size //póki nie sprawdzimy wszystkich wierzchołków w grafie for each node x of Graph if node x was not visited and there exist edge between x and current 4

x end for if distance[current] + edge weight between current and x < distance[x] distance[x] := distance[current] + distance between current and previous[x] := current VISITED[current] := 1 visited_nodes := visited_nodes + 1 //Wierzchołek current odwiedzono //zwiększyć licznik odwiedzonych wierzchołków for each vertex v in Graph //znajdujemy nowy wierzchołek current if vertex v was not visited and distance[v] < tmp tmp := distance[v] current := v end for tmp := infinity if current = target //doszliśmy do punktu końcowego! print "Path found" //wypisać na ekran ścieżka zaleziona i wypisać ścieżkę int u := target; while previous[u]!= -1 print u u := previous[u] print source end while ; print "Path not found" //ścieżka pomiędzy source i target nie istnieje end Djikstra Słowniczek: edge krawędź (linia łącząca dwa wierzchołki), ma wagę (weight) vertex wierzchołek, charakteryzowany przez numer wierzchołka source punkt startowy target punkt końcowy 5