PB161 Programování v jazyce C++ Přednáška 11

Podobné dokumenty
PB161 Programování v jazyce C++ Přednáška 11

PB161 Programování v jazyce C++ Přednáška 4

PB161 Programování v jazyce C++ Přednáška 8

PB161 Programování v jazyce C++ Přednáška 10

PB161 Programování v jazyce C++ Přednáška 9

PB161 Programování v jazyce C++ Přednáška 10

PB161 Programování v jazyce C++ Přednáška 5

PB161 Programování v jazyce C++ Přednáška 4

PB161 Programování v jazyce C++ Přednáška 5

PB přednáška (23. listopadu 2015)

PB161 Programování v jazyce C++ Přednáška 3

PB přednáška (12. října 2015)

PB161 Programování v jazyce C++ Přednáška 2

PB161 Programování v jazyce C++ Přednáška 3

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Jazyk C++ I. Polymorfismus

Programování v C++ 2, 4. cvičení

Programování v C++ 1, 5. cvičení

Ukazatele, dynamická alokace

Více o konstruktorech a destruktorech

Hrátky s funkcemi. PV173 Programování v C++11. Vladimír Štill, Jiří Weiser. Fakulta Informatiky, Masarykova Univerzita. 29.

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

Jazyk C++ 1. Blok 3 Objektové typy jazyka C++ Třída. Studijní cíl. Doba nutná k nastudování. Průvodce studiem

Jazyk C++ II. STL knihovna kontejnery část 1

Mělká a hluboká kopie

PB161 Programování v jazyce C++ Přednáška 9

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

Ukazka knihy z internetoveho knihkupectvi

konstruktory a destruktory (o)

přetížení operátorů (o)

Úvod do programovacích jazyků (Java)

Dědění, polymorfismus

PB161 Programování v jazyce C++ Přednáška 9

Programování v C++ 1, 6. cvičení

PB161 Programování v jazyce C++ Přednáška 2

Konec a tak. PB173 Programování v C++11. Vladimír Štill, Jiří Weiser. Fakulta Informatiky, Masarykova Univerzita. 15.

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

PŘETĚŽOVÁNÍ OPERÁTORŮ

PROGRAMOVÁNÍ V C++ CVIČENÍ. Michal Brabec

Jazyk C++ II. Šablony a implementace

Úvod do programovacích jazyků (Java)

Pokročilé programování v jazyce C pro chemiky (C3220) Statické proměnné a metody, šablony v C++

Programování v jazyce C a C++

Vector datový kontejner v C++.

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Úvod Třídy Rozhraní Pole Konec. Programování v C# Hodnotové datové typy, řídící struktury. Petr Vaněček 1 / 39

Generické programování

Programování v C++ 2, 7. cvičení

PB161 Programování v jazyce C++ Přednáška 3

PREPROCESOR POKRAČOVÁNÍ

typová konverze typová inference

Programování v C++ 1, 1. cvičení

Odvozené a strukturované typy dat

int ii char [16] double dd název adresa / proměnná N = nevyužito xxx xxx xxx N xxx xxx N xxx N

Konstruktory a destruktory

Jazyk C++ I. Šablony 2

PB161 Programování v jazyce C++ Přednáška 7

přetížení operátorů (o)

PB161 Programování v jazyce C++ Přednáška 7

Programování v C++ 3, 3. cvičení

Jazyk C# (seminář 6)

Dynamika objektů. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze

Ukazatel (Pointer) jako datový typ - proměnné jsou umístěny v paměti na určitém místě (adrese) a zabírají určitý prostor (počet bytů), který je daný

IB111 Úvod do programování skrze Python Přednáška 7

<surface name="pozadi" file="obrazky/pozadi/pozadi.png"/> ****************************************************************************

Funkční objekty v C++.

Objektově orientované programování

Šablony, kontejnery a iterátory

C++ přetěžování funkcí a operátorů. Jan Hnilica Počítačové modelování 19

PB161 Programování v jazyce C++ Přednáška 1

Programování v C++ 2, 8. cvičení

PB161 Programování v jazyce C++ Přednáška 1

Programování v C++, 2. cvičení

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Programování v C++ VI

Jazyk C++ I. Šablony

TŘÍDY POKRAČOVÁNÍ. Události pokračování. Příklad. public delegate void ZmenaSouradnicEventHandler (object sender, EventArgs e);

PB přednáška (26. října 2015)

8 Třídy, objekty, metody, předávání argumentů metod

Polymorfismus. Časová náročnost lekce: 3 hodiny Datum ukončení a splnění lekce: 30.března

IUJCE 07/08 Přednáška č. 6

Práce s polem a pamětí

Výrazy, operace, příkazy

Programování v jazyce C a C++

Jazyk C++ I. Polymorfismus

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

map, multimap - Asociativní pole v C++.

Výrazy, operace, příkazy

Ukazatele a pole. Chceme-li vyplnit celé pole nulami, použijeme prázdný inicializátor: 207 Čárka na konci seznamu inicializátorů

Jazyky C a C++ kompletní průvodce 2., aktualizované vydání. Miroslav Virius

ZPRO v "C" Ing. Vít Hanousek. verze 0.3

Pole stručný úvod do začátku, podrobně později - zatím statická pole (ne dynamicky) - číslují se od 0

- dělají se také pomocí #define - podobné (použitím) funkcím - předpřipravená jsou např. v ctype.h. - jak na vlastní makro:

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Struktura programu v době běhu

Programování II. Návrh programu I 2018/19

Abstraktní datové typy

Data, výrazy, příkazy

Zápis programu v jazyce C#

4. ZÁKLADNÍ POJMY Z OBJEKTOVĚ ORIENTOVANÉHO PROGRAMOVÁNÍ

Transkript:

PB161 Programování v jazyce C++ Přednáška 11 Pokročilé C++(17) povrchně Nikola Beneš 4. prosince 2018 PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 1 / 34

Organizační Dnešní přednáška co je nového v C++11, C++14, C++17 částečně rekapitulace částečně výhled dál (velmi povrchně) reklama na PV264 Advanced Programming in C++ Příští přednáška zvaná přednáška zkušenosti z praxe přednášející? nechte se překvapit PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 2 / 34

Moderní C++ zařazené do PB161 (rekapitulace + něco navíc) nullptr auto range-based for uniformní inicializace anonymní funkce lambdy unique_ptr default, delete override noexcept using PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 3 / 34

Rekapitulace: nullptr Proč je lepší než NULL? typově bezpečné není to makro implicitně se konvertuje na ukazatele bool PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 4 / 34

Rekapitulace: auto klíčové slovo žádající překladač o automatické odvození typu stejná pravidla jako pro odvozování šablonových parametrů s malou výjimkou pro std::initializer_list za chvíli Kdy je vhodné používat auto? víme, jaký bude výsledný typ, a ten je buď příliš škaredý (iterátory) jasně čitelný z okolního kódu, např. je někde přímo uvedený auto printer = myfactory.createinkprinter(); auto ptr = std::make_unique<listelement>(); v rozumné míře ve hlavičce range-based for for (const auto& person : people) { /*... */ } nebo nevíme, jaký bude výsledný typ (a nemáme to jak vědět) jak se tohle může stát? PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 5 / 34

Rekapitulace: range-based for Co se skrývá za následujícím cyklem? for (const auto& word : words) { std::cout << word << '\n'; } { } auto&& l = words; //??? auto i = std::begin( l), e = std::end( l); for(; i!= e; ++ i) { const auto& word = * i; std::cout << word << '\n'; } od C++17 technická změna: iterátory vrácené begin a end mohou být různého typu PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 6 / 34

Vlastní iterovatelné objekty Co musí objekt splňovat, abych přes něj mohl iterovat pomocí for? musí mít iterátory ty musí umět minimálně operátor ++ (prefixový), * (unární, dereference) a porovnávání pomocí == musí mít metodu begin(), která vrací iterátor musí mít metodu end(), která vrací iterátor Iterátorů je mnoho druhů už jste mohli vidět na http://en.cppreference.com/w/cpp/iterator PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 7 / 34

Uniformní inicializace Rekapitulace (viděli jsme) inicializace v C++03: použitím kulatých závorek nebo = u deklarace inicializace v C++11: kromě výše uvedeného navíc ještě složené závorky proč? Co se stane? std::string line(); Person person(std::string()); oba tyto řádky deklarují funkce toto je známo jako most vexing parse Inicializace složenými závorkami snaha o sjednocení syntaxe PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 8 / 34

Uniformní inicializace (pokr.) Sjednocení syntaxe pro inicializaci složenými závorkami lze použít složené závorky navíc: limituje přetypování pouze takové, které neomezuje rozsah typu navíc: v některých případech není nutno použít jméno typu std::string line{}; Person person{ std::string{} }; a tím je problém vyřešen, všechny objekty můžeme inicializovat stejnou syntaxí. (Skutečně?) lecture11_01.cpp PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 9 / 34

Inicializační seznam Statická inicializace (Céčkových) polí int array[] = { 1, 2, 3, 4, 0 }; Chceme totéž pro vektory std::vector<int> data{ 1, 2, 3, 4, 0 }; už víme, že tohle funguje, ale jak to funguje? typ std::initializer_list<t>, který umí chytat seznamy ve složených závorkách, má metody begin() a end() std::vector<t> má konstruktor vector(std::initializer_list<t>) bere se hodnotou (neznamená kopii seznamu!) můžete použít i v konstruktorech vlastních tříd PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 10 / 34

Inicializační seznam (pokr.) for (int i : { 1, 2, 3 }) { /*... */ } jaktože to funguje? výjimka pro auto Kdo má přednost (uniformní inicializace vs. inicializační seznam)? std::string s1("text"); std::string s2({ 't', 'e', 'x', 't' }); std::string s3(65, 't'); std::string s4{ "text" }; std::string s5{ 't', 'e', 'x', 't' }; std::string s6{ 65, 't' }; co bude obsahem řetězců? Pointa: Inicializační seznam má přednost. lecture11_02.cpp PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 11 / 34

Rekapitulace: anonymní funkce (lambdy) funkce, kterou můžeme definovat lokálně, v místě výrazu syntaktická zkratka za funkční objekt ve skutečnosti to je tzv. uzávěra (closure) může zachytávat proměnné z okolí std::vector<int> v; //... int sum = 0; std::for_each(v.begin(), v.end(), [&](int i) { sum += i; }); co se zde skrývá? lecture11_03.cpp PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 12 / 34

Anonymní funkce (lambdy) syntax [capture] (parameters) -> return_type { body } [capture] (parameters) { body } [capture] { body } nepovinné části lze vynechat návratový typ (dedukuje se automaticky) lze vynechat seznam parametrů (pak je prázdný) zachytávání [] nic [a] a hodnotou (konstantní [&b] b referencí [=] vše (co se vyskytuje v těle lambdy) hodnotou [&] vše (co se vyskytuje v těle lambdy) referencí kombinace, např. [&, a] vše referencí, ale a hodnotou [this] zachycení this [*this] zachycení kopie aktuálního objektu (C++17) PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 13 / 34

Anonymní funkce (lambdy) předávání/ukládání Co je lambda? lambda je dočasný objekt instance anonymní třídy každá lambda má vlastní třídu Jak předávat/ukládat lambdu? pokud nic nezachytává, lze ji přetypovat na ukazatel na funkci lze ji předat/uložit do auto šablonového parametru std::function<signatura funkce> používejte jen, pokud je to nutné proč? je to dražší a neumožňuje to inlining lecture11_04.cpp PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 14 / 34

Anonymní funkce (lambdy) C++14 Automatická dedukce typu parametrů [](auto x){ return ++x; } jako obvykle, pokud chceme explicitně referenci, musíme si o to říct: auto& Možnost inicializace v sekci capture int x = 4; int y = [&r = x, x = x + 1] { r += 2; return x + 2; }(); jaká bude na konci hodnota proměnných x a y? a co když přehodíme pořadí uvnitř sekce capture? lecture11_05.cpp PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 15 / 34

Rekapitulace: std::unique_ptr chytrý ukazatel myšlenka: unikátní vlastník alokované paměti automaticky dealokuje paměť v destruktoru nelze kopírovat, ale lze předávat vlastnictví pomocí move (o tom za chvíli) Upozornění: nenahrazuje běžné ukazatele, jen jedno z jejich použití nenahrazuje vytváření lokálních objektů (na zásobníku / uvnitř třídy) PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 16 / 34

Rekapitulace: default, delete default explicitní vynucení automaticky generovaných metod konstruktory (včetně kopírovacích) destruktory kopírovací přiřazovací operátor delete explicitní zabránění automatickému vytváření metod/funkcí konstruktory destruktory přiřazovací operátory libovolné funkce lecture11_06.cpp PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 17 / 34

Rekapitulace: override, final override sdělujeme překladači, že tato metoda překrývá virtuální metodu předka ochrana před nedodržením signatury (typu, const) final (o tomto jsme nemluvili) totéž, co override + navíc ochrana proti překrytí virtuální metody tuto metodu už potomci nesmí překrýt lze použít i s třídami: od třídy final se nesmí dědit raději moc nepoužívat, proč? porušuje to Open-Closed Principle neumožňujete rozšiřování funkcionality pokud nechcete umožnit překrývání metod, proč jsou vůbec virtuální? lecture11_07.cpp PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 18 / 34

Rekapitulace: noexcept operátor i specifikátor specifikátor může mít parametr typu bool (konstantní výraz) samotný noexcept je totéž, co noexcept(true) označuje metodu/funkci, že nebude vyhazovat výjimky pokud přesto něco vyhodí, volá se std::terminate přidání kvůli move sémantice (později) template<typename T> void dosomething(t& obj) noexcept(noexcept(obj.run())) { obj.run(); } template<typename T> void safewithsmallthings(t t) noexcept(sizeof(t) < 4) { //... } PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 19 / 34

Rekapitulace: using Hezčí typedef typedef int (*funcptr)(int, const char*); using func = int(int, const char*); using funcptr = func*; Umí být šablonované template<typename T> using Matrix = std::vector<std::vector<t>>; template<std::size_t N> using IntArray = int[n]; template<typename T> using Ptr = T*; PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 20 / 34

Další témata moderního C++ static_assert zobecněné konstantní výrazy (constexpr) move sémantika variadické šablony další chytré ukazatele SFINAE a jiné šablonové triky asynchronní zpracování, vlákna knihovny random, chrono, regex, C++17 budoucnost (C++2?) PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 21 / 34

Statický assert kontrola předpokladů během překladu vyhodnocení konstantního výrazu typu bool případné zahlášení chyby užitečné zejména v kombinaci se šablonami a tzv. type traits static_assert(sizeof(int) == 4, "This program only works with 32-bit int type."); template<typename T> class Container { static_assert(std::is_trivial<t>::value, "This class is only designed to work for trivial types".); //... }; lecture11_08.cpp PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 22 / 34

Zobecněné konstantní výrazy Vyhodnocení funkce během překladu specifikátor constexpr funkci lze volat i v době provádění programu v C++11 velmi omezené pouze jeden return podmínka řešitelná pouze pomocí operátoru?: v C++14 rozšířeno; funkce ale stále nesmí obsahovat: goto bloky try / catch a pár dalších v C++17 i constexpr lambdy lecture11_09.cpp PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 23 / 34

Move sémantika L-hodnoty (lvalues) původně: to, co může stát vlevo od přiřazení v C++: cokoli, co má adresu (trochu zjednodušeně) proměnná, reference, dereferencovaný ukazatel, P-hodnoty (rvalues) to ostatní dočasné objekty, číselné konstanty, Základní myšlenka move sémantiky když vím, že to, co jsem dostal je p-hodnota (dočasný objekt), můžu si s ní dělat, co chci proč? životnost dočasného objektu končí na konci výrazu rvalue reference: typ&& lecture11_10.cpp PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 24 / 34

Move sémantika použití Move konstruktor (pro třídy, které drží nějaký zdroj RAII) class IntArray { int* array; size_t size; public: //... IntArray(IntArray&& other) : array(other.array), size(other.size) { other.array = nullptr; other.size = 0; // we steal other's resources } }; Move přiřazovací operátor IntArray& operator=(intarray&& other) { /*... */ } PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 25 / 34

Move sémantika Rule of Three/Four and a Half běžná třída s pravidlem 3,5 se změní v třídu s pravidlem 4,5: stačí přidat konstruktor class A { public: A(const A& other) { /*... */ } ~A() { /*... */ } A& operator=(a other) { swap(other); return *this; } void swap(a& other) { using std::swap; //... } A(A&& other) { /*... */ } // NEW! PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 26 / 34

Move sémantika K čemu je to vlastně dobré? výkonostní optimalizace kopírovaní je drahé a my se mu takto umíme občas vyhnout kde se používá? kontejnery ve standardní knihovně (např. std::vector) tam, kde se spravují zdroje (RAII) i jinde (perfect forwarding) std::move funkce ze standardní knihovny přetypování na typ&& K tomuto objektu je možno se chovat, jako by byl dočasný. umožňuje (move konstruktorům) vykrást vnitřnosti objektu lecture11_11.cpp PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 27 / 34

Move sémantika a noexcept move konstruktory by měly pokud možno být deklarovány jako noexcept proč? std::vector od C++11 by rád používal přesouvání místo kopií při realokaci ale co když move konstruktor vyhodí výjimku? není možno garantovat návrat do konzistentního stavu proč tento problém není s kopírovacími konstruktory? pointa: std::vector používá move konstruktory, jen pokud jsou noexcept nebo neexistuje kopírovací konstruktor (v tom případě neplatí garance návratu do konzistentního stavu) PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 28 / 34

Variadické šablony Problém: v době psaní funkce nevím, kolik dostane parametrů řešení (C/C++03): void foo(int,...) použití va_args řešení C++11: variadické šablony typově bezpečné často používáno ve standardní knihovně lecture11_12.cpp PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 29 / 34

Chytré ukazatele std::shared_ptr<t> více vlastníků, počítání referencí poslední zhasne podstatně dražší než použití std::unique_ptr používejte jen, pokud skutečně potřebujete reference counting to většinou nepotřebujete na běžné použití stačí std::unique_ptr dost často stačí vůbec nealokovat paměť dynamicky (+ používat prostředků standardní knihovny) std::weak_ptr<t> doplněk k std::shared_ptr nepočítá se k referencím před použitím třeba konvertovat na std::shared_ptr PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 30 / 34

a další Nové části standardní knihovny od C++11 type traits (užitečné šablonové triky použivající SFINAE) regulární výrazy <regex> podpora paralelního programování vlákna, mutexy, podmínkové proměnné, asynchronní volání, lepší generování náhodných čísel <random> lepší zacházení s časem <chrono> unordered_* asociativní kontejnery implementované pomocí hashovacích tabulek PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 31 / 34

a další Nové části standardní knihovny od C++17 optional variant typově bezpečný union any string_view efektivní způsob předávání podřetězců bez kopírování nové metody existujících kontejnerů Nové části jazyka C++17 automatická dedukce parametrů pro třídy std::pair p{ 1, 3.14 }; tzv. folding výrazů lepší způsob zpracování variadických parametrů structured bindings rozbalování tuple apod. při inicializaci auto [iter, inserted] = m.emplace(key, value); constexpr if PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 32 / 34

Budoucnost C++2? koncepty ranges (algoritmy/iterátory s líným vyhodnocováním) porovnávací operátor <=> moduly (?) korutiny (coroutines) (?) https://en.cppreference.com/w/cpp/compiler_support https://en.wikipedia.org/wiki/c++20 PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 33 / 34

Závěrem PV264 Advanced Programming in C++ přednášky, materiály k předmětu apod. v angličtině dva domácí úkoly v první polovině semestru skupinový projekt v druhé polovině semestru https://www.fi.muni.cz/pv264 Přeji úspěšné zkouškové! PB161 přednáška 10: pokročilé C++(17) povrchně 4. prosince 2018 34 / 34