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

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

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

Virtuální metody - polymorfizmus

Programování v C++ VI

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

Abstraktní třída a rozhraní

24. listopadu 2013, Brno Připravil: David Procházka

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

Více o konstruktorech a destruktorech

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

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

Generické programování

Jazyk C++ I. Polymorfismus

Dědění, polymorfismus

Programování II. Polymorfismus

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

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

1. Dědičnost a polymorfismus

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

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

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

Pokročilé programování v jazyce C pro chemiky (C3220) Dědičnost tříd v C++

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

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

16. února 2015, Brno Připravil: David Procházka. Konstruktory a destruktory

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

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

Konstruktory a destruktory

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

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.

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

Jazyk C++ I. Šablony 2

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

Abstraktní třídy, polymorfní struktury

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

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

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.

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

Mělká a hluboká kopie

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

Obsah přednášky 9. Skrývání informací. Skrývání informací. Zapouzdření. Skrývání informací. Základy programování (IZAPR, IZKPR) Přednáška 9

Dynamická identifikace typů v C++.

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

Dědičnost. seskupování tříd do hierarchie. potomek získá všechny vlastnosti a metody. provádí se pomocí dvojtečky za názvem třídy.

Programování II. Abstraktní třída Vícenásobná dědičnost 2018/19

Úvod do programovacích jazyků (Java)

Funkční objekty v C++.

Výchozí a statické metody rozhraní. Tomáš Pitner, upravil Marek Šabo

11 Diagram tříd, asociace, dědičnost, abstraktní třídy

Základy objektové orientace I. Únor 2010

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

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

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

Přetěžování operátorů

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

Jazyk C++ I. Polymorfismus

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

Dědičnost (inheritance)

PREPROCESOR POKRAČOVÁNÍ

Osnova přednášky. Programové prostředky řízení Úvod do C# II. Přístup ke členům. Členy (Members)

Principy objektově orientovaného programování

Programování II. Dědičnost změna chování 2018/19

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

Výčtový typ strana 67

, Brno Připravil: David Procházka Návrhové vzory

Objektové programování

Vector datový kontejner v C++.

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

typová konverze typová inference

Programování v jazyce JavaScript

konstruktory a destruktory (o)

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

Jazyk C++ II. Šablony a implementace

SYSTÉMOVÉ PROGRAMOVÁNÍ Cvičení č.1

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

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

Jazyk C++ I. Šablony

Jazyk C# (seminář 3)

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

Objektově orientované programování v jazyce Python

Programování v jazyce C a C++

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

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

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

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

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

1. Programování proti rozhraní

Anotace. Objekt self, Zapouzdření, polymorfismus,

Objektov orientované programování. C++ Akademie SH. 7. Objektov orientované programování. Michal Kvasni ka. Za áte níci C++ 2.

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

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

C++ objektově orientovaná nadstavba programovacího jazyka C

Objektově orientované programování v jazyce Python

7. OBJEKTOVĚ ORIENTOVANÉ PROGRAMOVÁNÍ

7. přednáška - třídy, objekty třídy objekty atributy tříd metody tříd

Cvičení z programování v C++ ZS 2016/2017 Přemysl Čech

Mnohotvarost (polymorfizmus)

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

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

Připravil: David Procházka. Programovací jazyk C++

Transkript:

Dědičnost V objektově orientovaném programování je dědičnost způsob, jak vytvořit novou třídu použitím již existujících definic jiných tříd. Takto vytvořené třídy přebírají vlastnosti a metody svého předka a doplní k nim své vlastní. Co se nedědí: - konstruktor - lze jej vyvolat v konstruktoru odděděné třídy. - destruktor - je volán automaticky v destruktoru odvozené třídy - přetížené operátory =, new, delete Chování konstruktorů a destruktorů při dědění Pokud rodičovská třída nemá konstruktor (překladač tedy vytváří implicitní konstruktor) nebo má rodičovská třída prázdný konstruktor, není nutné jej volat v konstruktroru v odděděné třídě. Při vytváření instance třídy se tak nejprve vyvolá bezparametrický konstruktor nejvyšší nadtřídy, poté jejího potomka, atd., až se vyvolá požadovaný konstruktor pro instanci. class A A()cout << "Konstruktor tridy A"; class B: public A int y; B() cout << "Konstruktor tridy B"; Pokud je třeba vyvolat konstruktor předka se vstupními inicializačními parametry, volá se v konstruktoru potomka za dvojtečkou na začátku seznamu inicializátorů. class A A(int a) class B : public A B(int a, int b) : A(a) //spravne B(int a, int b) A(a) //spatne B(int a, int b) //spatne Pořadí volání destruktorů se děje v opačném pořadí než-li u konstruktorů. Nejprve se volá destruktor potomka a poté destruktor předka.

class Base Base() cout << "Konstruktor predka\n"; ~Base() cout << "Destruktor predka\n"; class Derived : public Base Derived() cout << "Konstruktor potomka\n"; ~Derived() cout << "Destruktor potomka\n"; int main ( void ) Derived d; return 0; Výpis na obrazovce: Konstruktor predka Konstruktor potomka Destruktor potomka Destruktor predka Překrývání metod Někdy ve třídě potomka potřebujeme, aby se implementace odděděných metod mírně lišily od metod třídy předka. V takovém případě můžeme tuto metodu překrýt. Ve třídě potomka napíšeme hlavičku metody stejnou jako ve třídě předka, ale dáme jí nové tělo. class Base void display() cout << "Třída Base\n"; class Derived : public Base void display() cout << "Třída Derived\n"; Derived d; d.display(); Base b; b.display(); Při překrývání metod můžeme narazit na jedno úskalí. Pokud vytvoříme např. třídu Zivocich, která bude mít vlastnost vek, konstruktor a přetíženou metodu OzviSe(string s="zivocich"). Od třídy Zivocich oddědíme třídu Pes, která překryje pouze jednu metodu OzviSe(). Druhá metoda OzviSe(string s) se tak pro třídu Pes stává metodou skrytou (nelze pro Psa použít). enum RasaPitbul, Jezevcik, Labrador, Kokrspanel

class Zivocich int vek; Zivocich(int v = 1)vek = v; cout << "zivocich "; string OzviSe()return "Jsem zivocich"; string OzviSe(string s)return s; class Pes: public Zivocich string name; Rasa rasa; Pes(int v, string n, Rasa r); string OzviSe()return "Haf"; Pes::Pes(int v=1, string n="hafik", Rasa r = Jezevcik ):Zivocich(v),name(n),rasa(r) Pes p(5); cout << p.ozvise(); cout << p.ozvise("vrr, haf, haf"); //nezna zavolat cin >> x; Virtuální metody Pozdní vazba (late binding; virtual call) - Je-li metoda nějaké třídy virtuální či čistě virtuální, pak všechny metody se stejným jménem, počtem a typy parametrů deklarované v potomcích třídy jsou považovány za různé implementace téže metody. - Která implementace se vybere, tedy které tělo bude zavoláno, se rozhoduje až za běhu programu podle skutečného typu celého objektu. - Použije se tělo z posledního potomka, který definuje tuto funkci a je součástí celého objektu. - Pozdní vazba má smysl pouze u vyvolání na objektu určeném odkazem Obyčejná (nevirtuální) metoda class A int f() return 1; class B : public A virtual int f() return 1;

A oa; A * paa = & oa; B ob; B * pbb = & ob; A * pab = pbb; paa->f(); // zavolá se metoda ze trídy A - A::f pbb->f(); // zavolá se metoda ze trídy B - B::f pab->f(); // zavolá se metoda ze trídy A - A::f Virtuální metoda class A virtual int f() return 1; class B : public A virtual int f() return 2; A oa; A * paa = & oa; B ob; B * pbb = & ob; A * pab = pbb; paa->f(); // zavolá se metoda ze trídy A - A::f pbb->f(); // zavolá se metoda ze trídy B - B::f pab->f(); // zavolá se metoda ze trídy B - B::f Čistě virtuální metoda - Deklarována bez definování těla - Tělo bude doplněno později u potomka Abstraktní třída - Třída obsahující nějaké čistě virtuální metody (přímo či v předcích), jejichž tělo ještě nebylo definováno... - Nelze do ní vytvořit instanci - Lze používat ukazatele na tuto třídu a vyvolávat metody této třídy - Typicky neobsahuje žádné datové položky class AbstractGraphicObject virtual void paint() = 0; //ciste virtualni metoda AbstractGraphicObject * next; Mnohonásobná dědičnost V jazyce C++ lze kromě jednoduché dědičnosti využít i mnohonásobnou dědičnost. Napsat kód pro vícenásobnou dědičnost je poměrně snadné viz. příklad: class A int a; class B

int b; class AB : public A, public B int ab; Problémy mohou nastat ve chvíli, kdy mají rodičovské třídy vlastnosti nebo metody se stejnými názvy. Potom k nim musíme ve třídě potomka přistupovat přes jméno rodičovské třídy a operátor :: nebo je můžeme v případě metod obě přetížit a získat tím metodu pouze jednu. class A class B class AB : public A, public B AB ab; ab.a::x = 5; // pouzije x z A ab.b::x = 6; // pouzije x z B class Hello void g() cout << "Hello World\n"; class Goodbye void g() cout << "Goodbye World\n"; class HelloGoodbye : public Hello, public Goodbye void g() //pretizi obe Hello::g() i Goodbye::g() Hello::g(); Goodbye::g(); HelloGoodbye hg; hg.g();

Mnohonásobná dědičnost společný prapředek Pokud dědíme od dvou (či více) tříd, které mají společného předka a nechceme mít vlastnosti a metody, které pocházejí od společného prapředka ve třídě zdvojené, stejně jako v předchozích příkladech, musíme využít virtuální dědičnost. class Animal int vek; Animal(int v = 1) vek = v; cout << "Animal " << vek << endl; virtual void eat() int getvek() return vek; class Mammal : public virtual Animal Mammal(int v = 1):Animal(v)cout << "Mammal " << vek << endl; virtual void walk() class WingedAnimal : public virtual Animal WingedAnimal(int v):animal(v)cout << "WingedAnimal " << vek << endl; virtual void flap() class Bat : public Mammal, public WingedAnimal Bat(int v):animal(v), Mammal(v), WingedAnimal(v)cout << "Bat " << vek << endl; //pokud nepotrebuji, aby se pro prapredka volal konstruktor s parametrem není nutne pouzit volani Animal(v). Bude automaticky zavolan implicitni konstruktor při volani konstruktoru Mammal. int main() Bat* bat = new Bat(5); return 0; Příklad: Vytvořte třídy hráč a zbraň. Zbraň bude mít jako vlastnost body, které zbraň bude přidávat hráči při útoku (tato třída bude představovat sečnou zbraň). Dále od třídy Zbran odděďte třídu PalnaZbran, která bude mít navíc jako vlastnosti velikost zásobníku a počet nábojů. Třídě PalnaZbran připište metody pro přidání nábojů do zásobníku (pozor nemůžete přidat více nábojů, než se do zásobníku vejde) a metodu, která vrací informaci o tom, jestli jsou ve zbrani ještě náboje. Vytvořte třídu hráč, která bude obsahovat jako vlastnosti hráčův útok, obranu, body na zdraví a zbraň, kterou hráč má u sebe (může to být palná nebo sečná zbraň). Všem třídám zapouzdřete vlastnosti, vytvořte konstruktory a metody set, get, které budete potřebovat. Dále ve třídě hráč vytvořte instanční metodu souboj (hráč, kterému bude tato metoda příslušet, bude vždy útočník). Výsledek souboje bude rozdíl mezi celkový útokem útočníka (útok hráče + útok od zbraně pozor u střelné zbraně kontrolujte, jestli v ní má hráč náboje) a obranou obránce. O tento rozdíl snižte zdraví obránce. V metodě main vytvořte dva hráče a nechte je spolu navzájem dvakrát bojovat.