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

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

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

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

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

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

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

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

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

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

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

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

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

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

PREPROCESOR POKRAČOVÁNÍ

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

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

Dědění, polymorfismus

Mělká a hluboká kopie

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

Více o konstruktorech a destruktorech

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

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

Zapouzdření. Tomáš Pitner, upravil Marek Šabo

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

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

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

konstruktory a destruktory (o)

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

Programování v jazyce C a C++

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 5

Generické programování

Programování v jazyce C a C++

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

Ukazatele, dynamická alokace

Základy objektové orientace I. Únor 2010

Úvod do programovacích jazyků (Java)

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

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

Objektové programování

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ý

Programování II. Polymorfismus

IB111 Programování a algoritmizace. Objektově orientované programování (OOP)

Dynamicky vázané metody. Pozdní vazba, virtuální metody

Teoretické minimum z PJV

Základy C++ I. Jan Hnilica Počítačové modelování 18

Datové typy v Javě. Tomáš Pitner, upravil Marek Šabo

Principy objektově orientovaného programování

Třídy. Instance. Pokud tento program spustíme, vypíše následující. car1 má barvu Red. car2 má barvu Red. car1 má barvu Blue.

PB přednáška (21. září 2015)

Seminář Java II p.1/43

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

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

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

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

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

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

Odvozené a strukturované typy dat

Jazyk C++ I. Polymorfismus

NPRG031 Programování II 1 / :25:46

NMIN201 Objektově orientované programování 1 / :36:09

Programování v C++ VI

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

Programování v Javě I. Leden 2008

Objektově orientované programování

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

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

Pokročilé programování v jazyce C pro chemiky (C3220) Třídy v C++

Konstruktory a destruktory

Kolekce ArrayList. Deklarace proměnných. Import. Vytvoření prázdné kolekce. napsal Pajclín

UJO Framework. revoluční architektura beans. verze

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

Šablony, kontejnery a iterátory

IRAE 07/08 Přednáška č. 1

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

PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1

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

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

Programování v Javě I. Únor 2009

Pokročilé programování v jazyce C pro chemiky (C3220) Pokročilá témata jazyka C++

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

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

Viditelnost (práva přístupu) Tomáš Pitner, upravil Marek Šabo

Abstraktní datové typy

Objektově orientované programování. Úvod

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

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

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

Dynamická alokace paměti

Jazyk C# (seminář 6)

Úvod do programovacích jazyků (Java)

Správné vytvoření a otevření textového souboru pro čtení a zápis představuje

Pokud neuvedeme override, vznikne v synu nová (nevirtuální) metoda (a pochopitelně se nezavolá, jak bychom

Základy programování (IZP)

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

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

1. Programování proti rozhraní

Přetěžování operátorů, dynamika objektů 2

Preprocesor. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze. Karel Richta, Martin Hořeňovský, Aleš Hrabalík, 2016

Transkript:

PB161 Programování v jazyce C++ Přednáška 2 Základy objektů Reference, const Testování Nikola Beneš 25. září 2017 PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 1 / 35

Jak funguje std::vector? (pro zvídavé) Typická implementace rezervovaná paměť, část z ní je obsazená tři ukazatele (nebo jeden ukazatel a dvě čísla) začátek rezervované paměti, konec obsazené, konec rezervované když je rezervovaná paměť plná, provede se alokace nové a prvky se do ní zkopírují (od C++11 přesunou) start endreserved end PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 2 / 35

Třídy, objekty, metody PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 3 / 35

Složené datové typy Znáte z C: struct Třídy v C++: class, struct rozšíření struktur o: přístupová práva metody prvky OOP (dědičnost, pozdní vazba, ) přístupová práva: public vidí všichni private vidí jen objekty dané třídy protected souvisí s dědičností class má implicitně právo private, struct má implicitně právo public Poznámka: Zatím používáme třídy jen jako lepší struct, k OOP se dostaneme později. PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 4 / 35

Složené datové typy (pokr.) Objekty v C++ proměnné jejichž typem je třída Atributy (správně členské proměnné member variables) jako položky struct jsou součástí stavu objektu Metody (správně členské funkce member functions) funkce, které nějak pracují s objekty smí číst/měnit atributy objektu [ukázka] PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 5 / 35

Metody Deklarace a definice metod deklarace uvnitř třídy (v hlavičkovém souboru) definice: uvnitř třídy (vhodné pro malé metody) jsou vždy inline odděleně (větší metody) class Person { std::string name; public: // deklarace s definicí void rename(std::string newname) { name = newname; // deklarace bez definice int getsalary(); PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 6 / 35

Metody (pokr.) Skrytý parametr this ukazatel na konkrétní objekt void Person::rename(std::string newname); // je jakoby void Person::rename(Person* this, std::string newname); // (to ovšem není validní C++) jimmy.rename("agent 007"); // je jakoby Person::rename(&jimmy, "Agent 007"); // (není C++) PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 7 / 35

Inicializace objektů Speciální metoda konstruktor jmenuje se stejně jako třída nemá návratový typ má tzv. inicializační sekci class Person { std::string name; int age; public: Person(std::string n, int a) : name(n), age(a) { std::cout << "New Person created:" << name << "\n"; [ukázka použití] PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 8 / 35

Inicializace objektů (pokr.) Inicializace atributů přímo v deklaraci třídy od C++11 class Person { std::string name; int age = 0; public: Person(std::string n) : name(n) { std::cout << "New Person created:" << name << "\n"; přednost má inicializační sekce konstruktoru to má význam, když definujeme více různých konstruktorů o přetěžování metod/funkcí apod. si řekneme více později PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 9 / 35

Inicializace v C++ Různé způsoby inicializace při deklaraci std::string one = "One"; // toto NENÍ přiřazení! std::string two{"two"; std::string three("three"); std::string empty{; std::string alsoempty; dočasný objekt std::cout << std::string(); std::cout << std::string{; std::cout << std::string("hello"); std::cout << std::string{"hello"; v inicializační sekci (podobně) PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 10 / 35

Inicializace v C++ (pokr.) Na co si dát pozor u primitivních typů a tříd s implicitním konstruktorem je zde rozdíl: int x; // neinicializováno int y{; // inicializováno na 0 int arraya[100]; // neinicializované pole int arrayb[100]{; // pole nul kulaté a složené závorky mohou mít u některých tříd různý význam std::string a{65, 'x'; // "Ax" std::string b(65, 'x'); // šedesát pět krát x Doporučení pokud je to možné, raději proměnné inicializujte používejte valgrind (na linuxu), případně Dr. Memory Pro zvídavé: http://en.cppreference.com/w/cpp/language/initialization PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 11 / 35

Jak navrhovat objekty Single Responsibility Principle (SRP) část tzv. principů SOLID (více později) každá třída (modul, funkce, ) by měla být zodpovědná za jednu konkrétní věc Heslo: Třída by měla mít jen jeden důvod ke změně. Princip zapouzdření (encapsulation) metody a atributy tříd jsou na jednom místě přístup k atributům třídy může být omezen právy PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 12 / 35

Rekapitulace Třídy a objekty Třídy v C++ složené datové typy Objekty hodnoty těchto datových typů Metody (členské funkce) funkce deklarované uvnitř tříd, mají skrytý parametr this ukazatel na aktuální objekt Konstruktor speciální metoda, která se volá při inicializaci objektu, může mít (a je doporučeno toho využívat co nejvíce) inicializační sekci Zatím zamlčeno (a řekneme si o tom později): destruktory přetěžování funkcí, metod, operátorů kopírovací konstruktory dědičnost virtuální metody, abstraktní třídy PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 13 / 35

Reference a const & PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 14 / 35

Motivace Viděli jsme minule parametry se předávají hodnotou (tj. kopie) někdy nechceme vytvářet kopie chceme parametr navenek změnit parametr je složitý datový typ a kopírování by bylo zbytečně drahé Práce s ukazateli (znáte z C) void swap(int *x, int *y) { // toto je C int temp = *x; *x = *y; *y = temp; Problémy s ukazateli? (NULL ukazatel, neinicializovaný ukazatel, ) PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 15 / 35

Reference Reference: slabší, ale bezpečnější forma ukazatele nemůže být NULL (od C++11 nullptr) nemůže se přesměrovat jinam musí být vždy inicializovaná funguje jako alias int a = 1; int b = 2; int& ref = a; // ref je reference na a // cokoli provedeme s ref, jako bychom provedli s a ref = b; ref += 7; // jaká je teď hodnota a, b? [ukázka: srovnání s C] PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 16 / 35

Reference vs. ukazatele Ukazatel může být neinicializovaný int* ptr; int& ref; // chyba při kompilaci Ukazatel může být nullptr int* ptr = nullptr; int& ref = nullptr; // chyba při kompilaci Ukazatel se může přesměrovat int a = 1; int b = 2; int* ptr = &a; ptr = &b; int& ref = a; ref = b; // v čem je rozdíl? PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 17 / 35

Reference Používat reference nebo ukazatele? pokud možno dávejte přednost referencím ukazatele používejte jen tam, kde dává smysl nullptr a přesměrování pro dynamickou alokaci jsou vhodnější chytré ukazatele (o těch později) Na co si dát pozor? nedržet si referenci na něco, co už přestalo existovat nevracet z funkcí reference na lokální proměnné [ukázka] PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 18 / 35

Klíčové slovo const Znáte (možná) z C deklarace konstant použití spolu s ukazateli Připomenutí: const a ukazatele int a = 1; int b = 2; int* ptrx = &a; const int* ptry = &a; int* const ptrz = &a; ptrx = &b; *ptrx = 7; ptry = &b; *ptry = 7; ptrz = &b; *ptrz = 7; Které řádky obsahují chybu? PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 19 / 35

Klíčové slovo const (pokr.) Použití s referencemi int a = 1; const int& cref = a; std::cout << cref << '\n'; // čtení je OK cref = b; // zápis/modifikace je chyba při kompilaci Význam konstantních referencí deklarujeme záměr neměnit proměnnou (read-only) zároveň ale nevytváříme kopii vhodné např. pro předávání větších objektů do funkcí viděli jsme minule (string, vector) PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 20 / 35

Reference a l/p-hodnoty l-hodnoty a p-hodnoty (lvalues and rvalues) l-hodnota je to, co může stát na levé straně přiřazení má adresu, má jméno p-hodnota je to, co může stát na pravé straně přiřazení číselná hodnota, dočasný objekt (v C++11 trochu složitější) Co chytají reference? konstantní reference chytá 1 všechno nekonstantní reference chytá jen l-hodnoty void f(const std::string& x) { /*... */ void g(std::string& x) { /*... */ int main() { std::string s = "XYZ"; f("abc"); g("def"); f(s); g(s); 1 správná anglická terminologie je an object binds to a reference PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 21 / 35

Konstantní metody class Person { int age; public: void setage(int a) { age = a; int getage() { return age; ; void f(const Person& person) { std::cout << person.getage() << '\n'; int main() { Person john; john.setage(20); f(john); Kde je problém? PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 22 / 35

Konstantní metody (pokr.) const metody pokud metoda nehodlá měnit vnitřní stav objektu, musíme ji takto označit klíčové slovo const za hlavičkou metody class Person { //... int getage() const { return age; ; překladač nás hlídá pokus o změnu stavu objektu v const metodě ohlásí jako chybu Doporučení deklarujte jako const všechny metody, které nemají měnit stav objektu PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 23 / 35

Konstantní atributy Použití const u atributů třídy atribut se dá nastavit pouze v inicializační sekci konstruktoru potom už se nedá vůbec změnit class Person { std::string name; int age; const std::string genome; //... ; využití: neměnné objekty neměnné části objektů (větší bezpečnost) PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 24 / 35

Doporučení Kde používat const? všude, kde dává smysl (tj. skoro všude) pište const všude a jen tehdy, pokud zjistíte, že danou proměnnou (atribut, referenci) budete chtít měnit, const smažte pište const ke všem metodám a jen tehdy, pokud zjistíte, že chcete, aby daná metoda měnila stav objektu, const smažte Proč? překladač vás hlídá větší bezpečnost jasně deklarujete svůj záměr větší čitelnost kódu překladač může využít pro optimalizace Poznámka: Programátoři v C++ v naprosté většině nepíšou const k parametrům funkcí předávaným hodnotou. Proč? PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 25 / 35

Hodnotová sémantika objektů class MyObject { int x, y; public: MyObject(int, int); int getx() const; int gety() const; void setx(int); void sety(int); ; void f(myobject a) { MyObject b(10, 12); a.setx(100); a = b; a.sety(50); b.setx(20); int main() { MyObject o(0, 0); f(o); return o.getx() + o.gety(); co se stane, když změníme hlavičku funkce f, aby brala referenci? jaké bude chování podobných programů v Pythonu či Javě? PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 26 / 35

Problém s kopírováním Možná jste si na slajdech všimli jednoho problému. class Person { std::string name; public: Person(std::string name) : name(name) { void rename(std::string newname) { name = newname; ; kde je problém? vstupní řetězec se kopíruje dvakrát jaké je řešení? PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 27 / 35

Řešení problému s kopírováním Klasické řešení class Person { std::string name; public: Person(const std::string& name) : name(name) { void rename(const std::string& newname) { name = newname; ; řešení ve stylu C++03 kopíruje se jen jednou pro tento předmět vyhovující PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 28 / 35

Řešení problému s kopírováním Moderní řešení (od C++11) class Person { std::string name; public: Person(std::string name) : name(std::move(name)) { void rename(std::string newname) { name = std::move(newname); ; výhoda: pokud je vstupem dočasný objekt, neděje se žádná kopie na std::move ještě narazíme k plnému pochopení je třeba znát rvalue reference navazující předmět PV264 pokud si nejste jisti, raději dejte (zatím) přednost klasickému řešení PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 29 / 35

Testování PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 30 / 35

Testování Programy obsahují chyby je to tak Testování programů důležitá součást vývoje různé úrovně testování unit testing testování malých jednotek kódu Nástroje pro unit testing velká řada různých frameworků my používáme https://github.com/philsquared/catch jeden hlavičkový soubor, bez závislostí testy se dají dělit do sekcí, podpora Behaviour-Driven Development jedno makro pro různé druhy porovnání PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 31 / 35

Použití Catch Psaní testů makro TEST_CASE TEST_CASE("Test case name", "[tag]") { // kód s asserty Dělení testů do sekcí makro SECTION sekce se dají zanořovat do sebe TEST_CASE("Some test") { // tato část se provede vždy SECTION("First section") { // tato část se provede při prvním průchodu SECTION("Second section") { // tato část se provede při druhém průchodu PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 32 / 35

Použití Catch (pokr.) Podmínky REQUIRE(condition); // musí být pravdivá REQUIRE_FALSE(condition); // nesmí být pravdivá Catch umí rozumně zacházet s jednoduchými porovnáními typu x == y, x < y apod. místo REQUIRE lze použít CHECK vykonávání testu se nezastaví, pokračuje se dál doporučení: preferujte CHECK; REQUIRE použijte tehdy, pokud další pokračování testu v případě nesplněné podmínky nedává smysl PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 33 / 35

Použití Catch (pokr.) Logování INFO(message) v případě, že v budoucnosti selže nějaký assert, zadaná zpráva se zobrazí zprávy jsou lokální na úrovni bloků uvnitř INFO možno řetězit výstupy pomocí << WARN zobrazí zprávu vždy FAIL zobrazí zprávu a neúspěšně ukončí test CAPTURE(var) totéž, co INFO("var := " << var) [ukázka] PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 34 / 35

Závěrečný kvíz https://kahoot.it PB161 přednáška 2: objekty, reference, const, testování 25. září 2017 35 / 35