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 7

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 3

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

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

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

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

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

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

PREPROCESOR POKRAČOVÁNÍ

Mělká a hluboká kopie

Dědění, polymorfismus

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

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

Více o konstruktorech a destruktorech

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

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

Základy objektové orientace I. Únor 2010

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

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

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

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

Ukazatele, dynamická alokace

konstruktory a destruktory (o)

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

Programování v jazyce C a C++

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

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

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

Programování v jazyce C a C++

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

Generické programování

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

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

Úvod do programovacích jazyků (Java)

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ý

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

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

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

Programování II. Polymorfismus

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

Programování v Javě I. Leden 2008

Šablony, kontejnery a iterátory

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

Principy objektově orientovaného programování

Jazyk C++ I. Polymorfismus

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

Teoretické minimum z PJV

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

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

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

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

Objektové programování

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

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

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

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

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

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

Abstraktní datové typy

Seminář Java II p.1/43

Programování v C++ VI

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

Bridge. Známý jako. Účel. Použitelnost. Handle/Body

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

Konstruktory a destruktory

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

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

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

Objektově orientované programování. Úvod

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

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

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.

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

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

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

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

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

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

Objektově orientované programování

Dynamická alokace paměti

Programování v C++ Úplnej úvod. Peta (maj@arcig.cz, SPR AG )

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

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

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

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

7. Datové typy v Javě

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

Funkční objekty v C++.

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

IAJCE Přednáška č. 8. double tprumer = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7; Console.Write("\nPrumerna teplota je {0}", tprumer);

Odvozené a strukturované typy dat

Základy programování (IZP)

Chování konstruktorů a destruktorů při dědění

Jazyk C++ I. Šablony 2

IRAE 07/08 Přednáška č. 2. atr1 atr2. atr1 atr2 -33

Transkript:

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

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 25. září 2018 2 / 30

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 25. září 2018 2 / 30

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 25. září 2018 2 / 30

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 25. září 2018 2 / 30

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 25. září 2018 2 / 30

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) PB161 přednáška 2: objekty, reference, const 25. září 2018 2 / 30

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) PB161 přednáška 2: objekty, reference, const 25. září 2018 2 / 30

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) PB161 přednáška 2: objekty, reference, const 25. září 2018 2 / 30

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) PB161 přednáška 2: objekty, reference, const 25. září 2018 2 / 30

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) PB161 přednáška 2: objekty, reference, const 25. září 2018 2 / 30

Třídy, objekty, metody PB161 přednáška 2: objekty, reference, const 25. září 2018 3 / 30

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 25. září 2018 4 / 30

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 lecture02_01.cpp PB161 přednáška 2: objekty, reference, const 25. září 2018 5 / 30

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(); lecture02_01.cpp PB161 přednáška 2: objekty, reference, const 25. září 2018 6 / 30

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++) rick.rename("grandpa Rick"); // je jakoby Person::rename(&rick, "Grandpa Rick"); // (není C++) PB161 přednáška 2: objekty, reference, const 25. září 2018 7 / 30

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"; } } lecture02_01.cpp PB161 přednáška 2: objekty, reference, const 25. září 2018 8 / 30

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 25. září 2018 9 / 30

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 25. září 2018 10 / 30

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 25. září 2018 11 / 30

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 Single Level of Abstraction (SLA) http://www.principles-wiki.net/principles:single_level_of_abstraction uvnitř jedné metody by se neměly míchat různé úrovně abstrakce preferujte menší metody, jednoduchá těla cyklů apod. PB161 přednáška 2: objekty, reference, const 25. září 2018 12 / 30

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 25. září 2018 13 / 30

Reference a const & PB161 přednáška 2: objekty, reference, const 25. září 2018 14 / 30

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? PB161 přednáška 2: objekty, reference, const 25. září 2018 15 / 30

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 25. září 2018 15 / 30

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] lecture02_02.cpp, lecture02_03.cpp PB161 přednáška 2: objekty, reference, const 25. září 2018 16 / 30

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 25. září 2018 17 / 30

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é lecture02_04.cpp PB161 přednáška 2: objekty, reference, const 25. září 2018 18 / 30

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, b = 2; int* ptrx = &a; const int* ptry = &a; int* const ptrz = &a; ptrx = &b; // A *ptrx = 7; // B ptry = &b; // C *ptry = 7; // D ptrz = &b; // E *ptrz = 7; // F Které řádky obsahují chybu? lecture02_05.cpp PB161 přednáška 2: objekty, reference, const 25. září 2018 19 / 30

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í nedává smysl pro primitivní typy a malé objekty viděli jsme minule (string, vector) PB161 přednáška 2: objekty, reference, const 25. září 2018 20 / 30

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); } PB161 přednáška 2: objekty, reference, const 25. září 2018 21 / 30 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ší) K čemu se mohou vázat reference? konstantní reference se smí vázat k čemukoli nekonstantní reference se smí vázat jen k l-hodnotám

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? lecture02_06.cpp PB161 přednáška 2: objekty, reference, const 25. září 2018 22 / 30

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 25. září 2018 23 / 30

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 25. září 2018 24 / 30

Doporučení Kde používat const? Proč? 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 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 Kde se spíš nepoužívá const? nepište je k návratovým hodnotám předávaným hodnotou nebývá zvykem je psát k parametrům funkcí předávaným hodnotou PB161 přednáška 2: objekty, reference, const 25. září 2018 25 / 30

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ě? (call-by-sharing) lecture02_07.cpp, lecture02_08.cpp PB161 přednáška 2: objekty, reference, const 25. září 2018 26 / 30

Problém s kopírováním Možná jste si na slajdech všimli jednoho problému. PB161 přednáška 2: objekty, reference, const 25. září 2018 27 / 30

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? PB161 přednáška 2: objekty, reference, const 25. září 2018 27 / 30

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 25. září 2018 27 / 30

Ř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 25. září 2018 28 / 30

Ř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 25. září 2018 29 / 30

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