c wyk ad 11 30 05 2013 n.
Download
Skip this Video
Download Presentation
C++ wykład 11 (30.05.2013)

Loading in 2 Seconds...

play fullscreen
1 / 39

C++ wykład 11 (30.05.2013) - PowerPoint PPT Presentation


  • 125 Views
  • Uploaded on

C++ wykład 11 (30.05.2013). Własne biblioteki, standardowa biblioteka szablonów STL. Kompilacja i łączenie. Plik jako jednostka kompilacji. Preprocesing – obsługa makr i dyrektyw włączających – dostarcza kompilatorowi jednostkę translacji.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'C++ wykład 11 (30.05.2013)' - lacy


Download Now An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
c wyk ad 11 30 05 2013

C++wykład 11 (30.05.2013)

Własne biblioteki, standardowa biblioteka szablonów STL

kompilacja i czenie
Kompilacja i łączenie
  • Plik jako jednostka kompilacji.
  • Preprocesing – obsługa makr i dyrektyw włączających – dostarcza kompilatorowi jednostkę translacji.
  • Kompilator analizuje jednostkę translacji w izolacji od reszty programu.
  • Fizyczna struktura programu (podział na pliki) powinna wynikać z logicznej struktury programu.
  • Rola linkera przy budowaniu programu albo biblioteki.
modu y
Moduły
  • Każdy większy program składa się z pewnej liczby oddzielnych części – modułów.
  • Moduł to kompletny fragment programu (moduł obliczeniowy, moduł we/wy, moduł prezentacji, itp).
  • Podział kodu na moduły porządkuje logikę programu.
  • Należy minimalizować zależności między modułami.
biblioteki
Biblioteki
  • Moduły, z których może korzystać wiele programów umieszcza się w oddzielnych skompilowanych plikach, zwanych bibliotekami.
  • Typy bibliotek w C++:
    • biblioteka statyczna jest dołączana do programu wynikowego na etapie linkowania;
    • biblioteka współdzielona jest dołączana do programu w trakcie ładowania programu do pamięci;
    • biblioteka dynamiczna jest dołączana do uruchomionego procesu w trakcie działania programu.
biblioteki1
Biblioteki
  • Biblioteka to zbiór klas, funkcji i zmiennych, z których mogą korzystać różne programy.
  • Biblioteka ma postać binarną – jej poszczególne fragmenty są skompilowane (biblioteka jest kolekcją plików obiektowych).
  • Korzystanie z bibliotek ułatwia programowanie (korzystamy z gotowych i sprawdzonych fragmentów kodu) i przyspiesza proces rekompilacji.
biblioteki2
Biblioteki
  • Wynikiem samej kompilacji pliku źródłowego (plik.c albo plik.cpp) jest plik plik.o pod Linuxem albo plik.obj pod Windowsem.
  • Biblioteki statyczne mają nazwy libmodul.a pod Linuxem albo modul.lib pod Windowsem.
  • Biblioteki dynamiczne mają nazwy libmodul.so pod Linuxem (tak jak biblioteki współdzielone) albo modul.dll pod Windowsem.
biblioteka statyczna
Biblioteka statyczna
  • Używając biblioteki statycznej przekazujemy jej archiwum linkerowi w czasie kompilacji. Linker wyszukuje w nim tylko tych plików obiektowych, które są niezbędne do działania naszego programu i kopiuje je bezpośrednio do programu.
  • Program wynikowy korzystający z biblioteki statycznej jest obszerniejszy ale szybciej się ładuje do pamięci.
  • Program wynikowy zlinkowany z biblioteką statyczną jest niezależny od plików zewnętrznych.
  • Uaktualnienie biblioteki wymaga rekompilacji programu.
biblioteka statyczna1
Biblioteka statyczna

lib.cpp

g++

lib.o

prog.cpp

ar

g++

static library

prog.o

linker

g++

a.out

loader

ssh

memory

biblioteka wsp dzielona
Biblioteka współdzielona
  • Programy korzystające biblioteki współdzielonej nie zawierają bezpośrednio kodu z tej biblioteki a tylko referencję do niej.
  • Program wynikowy korzystający z biblioteki współdzielonej jest chudszy ale wolniej ładuje się do pamięci (biblioteki współdzielone są odszukiwane i ładowane do pamięci razem z programem).
  • Program wynikowy skompilowany z biblioteką współdzieloną jest zależny od plików zewnętrznych.
  • Zmodyfikowanie biblioteki współdzielonej spowoduje zmianę w działaniu programu ale bez jego ponownej kompilacji.
biblioteka wsp dzielona1
Biblioteka współdzielona

prog.cpp

g++

lib.cpp

prog.o

g++

lib.o

linker

g++

g++

shared library

a.out

loader

ssh

memory

biblioteka dynamiczna
Biblioteka dynamiczna
  • Programy korzystające bibliotek dynamicznych nie zawierają bezpośrednio kodu z tej biblioteki ale muszą korzystać ze specjalnych metod włączania takich bibliotek w trakcie działania programu (plik nagłówkowy <dlfcn.h>).
  • Program wynikowy korzystający z biblioteki dynamicznej jest chudszy i szybciej ładuje się do pamięci, ale działa wolniej (biblioteki dynamiczne można załadować w dowolnym momencie w trakcie działania programu).
  • Program wynikowy skompilowany z biblioteką dynamiczną jest zależny od plików zewnętrznych.
  • Zmodyfikowanie biblioteki dynamicznej spowoduje zmianę w działaniu programu ale bez jego ponownej kompilacji.
biblioteka dynamiczna1
Biblioteka dynamiczna

prog.cpp

g++

prog.o

lib.cpp

linker

g++

g++

lib.o

a.out

g++

dynamic library

loader

a.out

ssh

memory

tworzenie bibliotek pod linuxem
Tworzenie bibliotek (pod Linuxem)

Tworzenie programu bez dołączanych bibliotek.

  • Załóżmy, że mamy pliki src1.cpp, src2.cpp i src3.cpp, które stanowią moduł obliczeniowy oraz plik prog.cpp, który będzie korzystał z funkcji i klas zdefiniowanych w module obliczeniowym.
  • Aby skompilować cały program razem z modułem obliczeniowym należy wydać polecenie:$ g++ -Wall -ansi -pedantic src1.cpp src2.cpp src3.cpp prog.cpp -o calculation
  • Aby skompilować cały program razem z modułem obliczeniowym i statycznie zlinkować z innymi bibliotekami (rozmiar programu wynikowego będzie znacznie większy) należy wydać polecenie:$ g++ -static …
  • Aby uruchomić skompilowany program należy wydać polecenie:$ ./calculation
  • Aby sprawdzić z jakimi bibliotekami jest linkowany program i jakie symbole są w nim użyte należy wydać polecenie:$ ldd calculation$ nm calculation
tworzenie bibliotek pod linuxem1
Tworzenie bibliotek (pod Linuxem)

Program korzystający z biblioteki statycznej.

  • Najpierw kompilujemy pliki źródłowe do plików obiektowych:$ g++ -c -Wall -ansi -pedantic src1.cpp src2.cpp src3.cpp
  • Następnie łączymy pliki obiektowe do jednego pliku bibliotecznego libsrc.a:$ ar crs libsrc.a src1.o src2.o src3.o
  • Na koniec należy skompilować plik z programem i zlinkować go z biblioteką:$ g++ -c -Wall -ansi -pedantic prog.cpp$ g++ -o calculation prog.o –L. –lsrc
  • Teraz można uruchomić skompilowany program:$ ./calculation
  • Wyjaśnienie:
    • opcja -Lścieżka określa ścieżkę do biblioteki,
    • opcja -lbiblioteka określa nazwę biblioteki.
tworzenie bibliotek pod linuxem2
Tworzenie bibliotek (pod Linuxem)

Program korzystający z biblioteki współdzielonej.

  • Najpierw kompilujemy pliki źródłowe z opcją -fpic do plików obiektowych:$ g++ -fpic –c -Wall -ansi -pedantic src1.cpp src2.cpp src3.cpp
  • Następnie łączymy pliki obiektowe do jednego pliku bibliotecznego libsrc.so:$ g++ –fpic -shared -o libsrc.so src1.o src2.o src3.o
  • Na koniec należy skompilować plik z programem i wlinkować do niego informacje o bibliotece:$ g++ -Wall -ansi -pedantic prog.cpp$ g++ -o calculation prog.o –L. –lsrc
  • Przed uruchomieniem programu trzeba zapisać w zmiennej środowiskowej LD_LIBRARY_PATH ścieżkę do biblioteki:$ export LD_LIBRARY_PATH="LD_LIBRARY_PATH:ścieżka"
  • Teraz można uruchomić skompilowany program:$ ./calculation
tworzenie bibliotek pod linuxem3
Tworzenie bibliotek (pod Linuxem)

Program korzystający z biblioteki dynamicznej.

  • Bibliotekę dynamiczną przygotowujemy tak samo jak bibliotekę współdzieloną libsrc.so:$ g++ -fpic –c -Wall -ansi -pedantic src1.cpp src2.cpp src3.cpp $ g++ –fpic -shared -o libsrc.so src1.o src2.o src3.o
  • Na koniec należy skompilować plik z programem i dołączyć do niego dynamicznego linkera opcją -ldl:$ g++ -Wall -ansi -pedantic prog.cpp$ g++ -o calculation prog.o –ldl
  • Teraz można uruchomić skompilowany program:$ ./calculation
  • Wyjaśnienie:
    • aby skorzystać z dynamicznego linkera należy do programu włączyć plik nagłówkowy <dlfcn.h>;
    • aby załadować dynamiczną bibliotekę trzeba skorzystać z funkcji dlopen, dlsym, dlerror i dlclose.
nazwy zewn trzne
Nazwy zewnętrzne
  • Nazwa jest łączona zewnętrznie jeśli można jej używać w jednostkach translacji innej niż ta, w której ją zdefiniowano.
  • Nazwę zewnętrzną deklaruje się za pomocą słowa extern.
  • Funkcja wbudowana musi być zdefiniowana w każdej jednostce translacji za pomocą identycznej definicji; ta sama reuła odnosi się do funkcji i klas szablonowych.
nowo ci z c 11 szablony zewn trzne i aliasy szablon w
Nowości z C++11 – szablony zewnętrzne i aliasy szablonów
  • C++ musi stworzyć instancję szablonu zawsze kiedy napotka w pełni określony szablon w jednostce translacyjnej. W starszym C++ nie jest bowiem możliwe wstrzymanie tworzenia instancji szablonu w takiej sytuacji.
  • C++11 wprowadza ideę szablonów zewnętrznych w celu zablokowania tworzenia instancji w jednostce translacyjnej. Przykład:extern template class std::vector<MojaKlasa>;
  • W C++11 można używać aliasów dla szablonów. Przykład:template <typename T> using Vec = std::vector<T,MyAlloc<T>>;
slide19
STL
  • STL (ang. Standard Template Library) to standardowa biblioteka wzorców w C++.
  • Wszystkie składniki STL są wzorcami.
  • STL jest rdzeniem biblioteki standardowej C++.
  • Wszystkie identyfikatory w bibliotece standardowej C++ zdefiniowane są w przestrzeni nazw std.
  • Zaleta STL – mnóstwo gotowych szablonów klas pozwalających programować na wyższym poziomie abstrakcji.
  • Wada STL – brak oczywistości (koniecznie czytaj dokumentację)
slide20
STL
  • Biblioteka STL składa się z kilku modułów:
    • strumienie we/wy,
    • łańcuchy i wyrażenia regularne,
    • kontenery i iteratory,
    • algorytmy i obiekty funkcyjne,
    • wielowątkowość i przetwarzanie współbieżne,
    • internacjonalizacja,
    • klasy narzędziowe.
slide21
Pary
  • Szablon struktury pair<> (zdefiniowany w <utility>) umożliwia potraktowanie dwóch wartości jako pojedynczego elementu.
  • Para posiada dwa pola: first i second.
  • Para posiada konstruktor dwuargumentowy oraz domyślny i kopiujący.
  • Pary można porównywać (operatory == i <).
  • Istnieje szablon funkcji make_pair() do tworzenia pary (typy danych są rozpoznawane przez kompilator po typach argumentów).
  • Przykłady:void f (std::pair<int, const char *>);void g (std::pair<const int, std::string>);…std::pair<int, const char *> p(44,”witaj”);f(p); // wywołuje domyślny konstruktor kopiującyg(p); // wywołuje konstruktor wzorcowyg(std::make_pair(44,”witaj”)); // przekazuje dwie // wartości jako parę z wykorzystaniem konwersji // typów
  • Pary są wykorzystywane w kontenerach map i multimap.
tuple
Tuple
  • W C++11 zdefiniowano tuple do przechowywania wielu wartości a nie tylko dwóch (szablon tuple<> jest analogią do szblony pary pair<>).
  • Tupla posiada wiele ponumerowanych pól, do których dostęp mamy za pomocą metody get<i>.
  • Tupla posiada konstruktor wieloargumentowy oraz domyślny i kopiujący.
  • Tuple można porównywać za pomocą operatorów porównań (porównywanie leksykograficzne).
  • Istnieje szablon funkcji make_tuple() do tworzenia tupli (typy danych są rozpoznawane przez kompilator po typach argumentów).
  • Istnieje szablon funkcji tie() do tworzenia tupli z referencjami (jako argumenty podaje się zmienne).
  • Szablon tuple_size<tupletype>::value służy do podania liczby elementów w tupli.
  • Szablon tuple_element<idx,tupletype>::type służy do podania typu elementu o indeksie idx w tupli.
sprytne wska niki
Sprytne wskaźniki
  • Sprytne wskaźniki są zdefiniowane w pliku nagłówkowym <memory>.
  • Zastąpienie szablonu auto_ptr<>.
  • Szablon klasy shared_pointer<> – wiele takich sprytnych wskaźników może przechowywać wskaźnik do tego samego obiektu, tak że obiekt ten oraz związane z nim zasoby zostaną zwolnione dopiero po likwidacji ostatniego sprytnego wskaźnika.
  • Szablon klasy unique_pointer<> – tylko jeden sprytny wskaźnik może przechowywać wskaźnik do tego danego obiektu.
ograniczenia liczbowe
Ograniczenia liczbowe
  • Typy numeryczne posiadają ograniczenia zależne od platformy i są zdefiniowane w szablonie numeric_limits<> (zdefiniowany w <limits>, stałe preprocesora są nadal dostępne w <climits> i <cfloat>).
  • Wybrane składowe statyczne szablonu numeric_limits<>: is_signed, is_integer, is_exact, is_bounded, is_modulo, has_infinity, has_quiet_NaN, min(), max(), epsilon().
  • Przykłady:numeric_limits<char>::is_signed;numeric_limits<short>::is_modulo;numeric_limits<long>::max();numeric_limits<float>::min();numeric_limits<double>::epsilon();
minimum i maksimum
Minimum i maksimum
  • Obliczanie wartości minimalnej oraz maksymalnej:template <class T>inline const T& min (const T &a, const T &b) { return b<a ? b : a; }template <class T>inline const T& max (const T &a, const T &b) { return a<b ? b : a; }
  • Istnieją też wersje tych szablonów z komparatorami (funkcja lub obiekt funkcyjny):template <class T, class C>inline const T& min (const T &a, const T &b, C comp) { return comp(b,a) ? b : a; }template <class T>inline const T& max (const T &a, const T &b, C comp) { return comp(a,b) ? b : a; }
minimum i maksimum1
Minimum i maksimum
  • Przykład 1:bool int_ptr_less (int *p, int *q) { return *p<*q; }…int x = 33, y = 44;int *px = &x, *py = &y;int *pmax = std::max(px,py,int_ptr_less);
  • Przykład 2:int i;long l;…l = max(i,l); // BŁĄD // niezgodne typy argumentówl = std::max<long>(i,l); // OK
zamiana warto ci
Zamiana wartości
  • Zamiana dwóch wartości:template <class T>inline void swap (T &a, T &b) { T tmp(a); a = b; b = tmp; }
  • Przykład:int x = 33, y = 44;…std::swap(x,y);
operatory por wnywania
Operatory porównywania
  • Cztery funkcje szablonowe (zdefiniowane w <utility>) na podstawie operatorów == i < definiują operatory porównań !=, <=, >= i >.
  • Funkcje te są umieszczone w przestrzeni nazw std::rel_ops.
  • Przykład:class X { …public: bool operator== (const X &x) const throw(); bool operator< (const X &x) const throw(); …};…void foo () { using namespace std::rel_ops; X x1, x2; … if (x1!=x2) { … } …}
kontenery
Kontenery
  • Kontenery służą do przechowywania i zarządzania kolekcjami danych.
  • Rodzaje kontenerów:
    • Kontenery sekwencyjne, gdzie każdy element ma określoną pozycję. Na przykład: vector, deque, list.
    • Kontenery uporządkowane (w tym asocjacyjne), gdzie pozycja elementu zależy od jego wartości. Na przykład: set, multiset, map, multimap.
elementy kontener w
Elementy kontenerów
  • Elementy kontenerów muszą spełniać wymagania podstawowe:
    • element musi być kopiowalny (konstruktor kopiujący),
    • element musi być przypisywalny (przypisanie kopiujące),
    • element musi być zniszczalny (publiczny destruktor).
  • W pewnych sytuacjach elementy kontenerów muszą spełniać wymagania dodatkowe:
    • konstruktor domyślny (utworzenie niepustego kontenera),
    • operator porównywania == (wyszukiwanie),
    • operator porównywania < (kryterium sortowania).
semantyka warto ci a semantyka referencji
Semantyka wartości a semantyka referencji
  • Kontenery STL realizują semantykę wartości: tworzą wewnętrzne kopie swoich elementów oraz zwracają kopie tych elementów.
  • Semantykę referencji można zaimplementować samodzielnie za pomocą inteligentnych wskaźników – wskaźniki te mają umożliwiać zliczanie referencji dla obiektów, do których odnoszą się wskaźniki.
kontenery sekwencyjne wektory
Kontenery sekwencyjne– wektory
  • Wektor vector<> (zdefiniowany w <vector>) przechowuje swoje elementy w tablicy dynamicznej.
  • Uzyskujemy szybki dostęp do każdego elementu za pomocą indeksowania.
  • Dołączanie i usuwanie elementów na końcu wektora jest bardzo szybkie, ale wstawienie lub usunięcie elementu ze środka zabiera więcej czasu.
  • Przykład:vector<int> coll;…for (int i=1; i<=6; ++i) coll.push_back(i);…for (int i=0; i<coll.size(); ++i) cout << coll[i] << ’ ’;cout << endl;
kontenery sekwencyjne kolejki o dw ch ko cach
Kontenery sekwencyjne– kolejki o dwóch końcach
  • Kolejka o dwóch końcach deque<> (zdefiniowana w <deque>) przechowuje swoje elementy w tablicy dynamicznej, która może rosnąć w dwie strony.
  • Uzyskujemy szybki dostęp do każdego elementu za pomocą indeksowania.
  • Dołączanie i usuwanie elementów na końcu i na początku kolejki jest bardzo szybkie, ale wstawienie lub usunięcie elementu ze środka zabiera więcej czasu.
  • Przykład:deque<float> coll;…for (int i=1; i<=6; ++i) coll.push_front(i*1.234);…for (int i=0; i<coll.size(); ++i) cout << coll[i] << ’ ’;cout << endl;
kontenery sekwencyjne listy
Kontenery sekwencyjne– listy
  • Lista list<> (zdefiniowana w <list>) przechowuje swoje elementy w liście dwukierunkowej.
  • W listach nie ma swobodnego dostępu do elementów kolekcji.
  • Dołączanie i usuwanie elementów na końcu i na początku listy jest bardzo szybkie, ale dostanie się do elementu ze środka zabiera dużo czasu.
  • Przykład:list<char> coll;…for (char c=’a’; c<=’z’; ++c) coll.push_back(c);…while (!coll.empty()) { cout << coll.front() << ’ ’; coll.pop_front(); }cout << endl;
kontenery sekwencyjne a cuchy i tablice
Kontenery sekwencyjne– łańcuchy i tablice
  • Obiektów klas łańcuchowych, czyli basic_string<>, string i wstring, można używać jak kontenerów sekwencyjnych. Są one podobne w zachowaniu do wektorów.
  • Innym rodzajem kontenera może być tablica. Nie jest to klasa i nie ma żadnych metod ale konstrukcja STL umożliwia uruchamianie na tablicach różnych algorytmów (tak jak na kontenerach).
kontenery uporz dkowane
Kontenery uporządkowane
  • Kontenery uporządkowane wykonują automatycznie sortowanie swoich elementów.
  • Asocjacyjne kontenery uporządkowane przechowują pary klucz-wartość (odpowiednio first i second) i sortowanie następuje po kluczach.
  • Domyślnie elementy lub klucze są porządkowane przy pomocy operatora <.
  • Kontenery uporządkowane są implementowane w postaci zrównoważonych drzew BST (drzewa czerwono-czarne).
  • Wszystkie kontenery uporządkowane posiadają domyślny parametr wzorca służący sortowaniu (domyślnym jest operator <).
  • Rodzaje kontenerów: zbiory set<>, wielozbiory multiset<>, mapy map<> i multimapy multimap<>.
adaptatory kontener w
Adaptatory kontenerów
  • Adaptatory kontenerów to kontenery wykorzystujące ogólną strukturę innych kontenerów do realizacji pewnych specyficznych potrzeb.
  • Adaptatorami kontenerów są stosy stack<>, kolejki queue<> i kolejki priorytetowe priority_queue<>.
iteratory
Iteratory
  • Iterator to specjalny obiekt, który potrafi iterować po elementach kolekcji.
  • Iterator ma zaimplementowaną semantykę wskaźnika – posiada operator wyłuskania elementu *, operatory przechodzenia do elementówsąsiednich ++ i -- oraz operatory porównywania pozycji == i !=.
  • Wszystkie kontenery udostępniają funkcje tworzące iteratory do nawigowania po ich elementach – funkcja begin() zwraca iterator wskazujący na pozycję z pierwszym elementem w kolekcji a funkcja end() zwraca iterator wskazujący pozycję za ostatnim elementem.
  • Każdy kontener definiuje dwa typy iteratorów – kontener::iterator przeznaczony do iterowania po elementach z możliwością odczytu i zapisu oraz kontener::const_iterator przeznaczony do iterowania po elementach tylko z możliwością odczytu.
iteratory1
Iteratory
  • Przykład 1:list<char> coll;…list<char>::const_iterator pos;for (pos=coll.begin(); pos!=coll.end(); ++pos) cout << *pos << ’ ’;cout << endl;
  • Przykład 2:list<char> coll;…list<char>::iterator pos;for (pos=coll.begin(); pos!=coll.end(); ++pos) *pos = toupper(*pos);
ad