C wyk ad 11 30 05 2013
Download
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


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>>;


STL szablonów

  • 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ę)


STL szablonów

  • 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.


Pary szablonów

  • 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 szablonów

  • 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 szablonów

  • 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 szablonów

  • 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 szablonów

  • 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 szablonów

  • 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 szablonów

  • 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 szablonów

  • 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 szablonów

  • 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 szablonó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 szablonówa 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 szablonów– 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 szablonów– 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 szablonów– 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 szablonów– ł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 szablonów

  • 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 szablonó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 szablonów

  • 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 szablonów

  • 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