Objektorienterad programmering forts Fordon Tåg Båt Bil Flygplan 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Hur är arv implementerat? Drawable position bitmap Persistent storage_file_name object_id Box bredd hojd Cirkel centrum radie Linje end_a end_b Bilregpost agare marke regnr Bankkonto agare saldo Text_Box text font Pil riktning 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Implementation av arv Cirkel mincirkel; datamedlemmar från basklassen position bitmap datamedlemmar från basklassen centrum radie underklass-specifika datamedlemmar 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Vad ärvs? medlemsfunktioner ärvs medlemsdata ärvs friends (vänner) ärvs inte konstruktor ärvs inte basklassens konstruktor anropas, vanligen från initieringslistan för att sätta rätt värden i basklassdelen en nivå upp kan man anropa 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Åtkomst av överklassmedlemmar protected: int x; MyBaseClass A myaobj1; x B mybobj; x SubClassA SubClassB A myaobj2; x doIt() ? doIt() 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Virtuell funktion Komma åt subtyp-specifik implementation av virtuella funktionsanrop från bastypen den virtuella hanteringen fungerar bara om objektet hanteras via pekare eller referens statiskt allokerat objekt ÄR av den statiska typen 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Implementation av objekt med statiska och virtuella metoder type_info för Myclass int x float f _vptr_Myclass Myclass::print(ostream &) Myclass::draw() Myclass::~Myclass() Virtual table för Myclass static int Myclass::noOfObjs static int Myclass::getNoOfObjs() int Myclass::get_x() Virtuella metoder nås via vptr 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Pure virtual function class Drawable { virtual void draw() = 0; ... Definierar (en del av) ett snitt utan att implementera det class Drawable { virtual void draw() = 0; ... “= 0” markerar pure virtual function 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Abstrakt överklass En klass med en eller flera pure virtual functions är en abstrakt överklass. En klass med bara pure virtual functions (dvs ingen funktion är implementerad i den) är en rent abstrakt överklass. Syftet med den är bara att specificera ett snitt som underklasserna ska tillhandahålla 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Arv av beteende Ger även arv av implementation Synligt arv Ger även arv av implementation utom då man jobbar med pure virtual function/rent abstrakta överklasser 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Arv av implementation Privat eller skyddat arv Stack teststack; teststack.push(x); teststack.push(y); t=teststack.pop(); class Stack : private Vector { public: push(Elem e) {/* peta i vektorn */} Elem pop() { /* peta i vektorn */} } Vad händer om man använder public inheritance istället? teststack.push_back(e); t=teststack[10]; Vi får ett väldigt fult anropssnitt! 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
...men en stack är inte en vektor Snyggare, renare, med en vektor som beståndsdel i stället för arv: class Stack { public: push(Elem e) { theStack.pushBack(e); } Elem pop() { /* ... */ } private: Vector theStack; } 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Konstruktor-destruktor och arv När ett objekt skapas sker följande: 1. Konstruktorn för ev. överklass anropas alltid först. 2. Konstruktorerna för den aktuella klassens datamedlemmar anropas 3. Satserna i den aktuella klassens konstruktor exekveras. När ett objekt tas bort sker följande: 1. Satserna i den aktuella klassens destruktor exekveras. 2. Destruktorerna för den aktuella klassens datamedlemmar anropas 3. Destruktorn för ev. överklass anropas. 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Multipelt arv Drawable Persistent position storage_file_name bitmap move() position bitmap Persistent save() restore() storage_file_name object_id Persistent_drawable Box length width Circle center radius Line end_a end_b 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Multipelt arv: iostream format_state condition_state locale streambuf (inte riktigt rätt) class istream : public ios class ostream : public ios istream ostream gcount xxx ifstream iostream ofstream yyy class iostream : public istream, public ostream fstream 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Kompileringsfel - dock endast vid iostream object??? istream object ostream object över- klass- delen från ios över- klass- delen från ios format_state condition_state locale streambuf gcount format_state condition_state locale streambuf gcount format_state condition_state locale streambuf xxx från istream istreams “egen” underklassbit ostreams “egen” underklassbit format_state condition_state locale streambuf xxx från ostream Kompileringsfel - dock endast vid försök att accessa de dubblerade delarna! yyy iostreams “egen” underklassbit 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Multipelt arv: iostream format_state condition_state locale streambuf med virtual inheritance class istream : virtual public ios class ostream : virtual public ios istream ostream gcount xxx ifstream iostream ofstream yyy class iostream : public istream, public ostream fstream 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Virtual inheritance en enda ios-bit! virtuell basklass iostream object format_state condition_state locale streambuf gcount en enda ios-bit! virtuell basklass från istream xxx yyy iostreams “egen” underklassbit från ostream 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Konstruktor-destruktor och arv multipelt Konstruktor-destruktor och arv När ett objekt skapas sker följande: 1. Konstruktorn för ev. överklass anropas alltid först. 2. Konstruktorerna för den aktuella klassens datamedlemmar anropas 3. Satserna i den aktuella klassens konstruktor exekveras. i deriveringslistans turordning När ett objekt tas bort sker följande: 1. Satserna i den aktuella klassens destruktor exekveras. 2. Destruktorerna för den aktuella klassens datamedlemmar anropas 3. Destruktorn för ev. överklass anropas. baklänges enligt deriveringslistans turordning 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
skydda konstruktorn på abstrakt överklass Drawable rita() flytta() position bitmap class Drawable { protected: Drawable(); ….. Box bredd hojd Cirkel centrum radie Linje end_a end_b Varför inte private? Text_Box text font Pil riktning byt_ riktning() 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
Virtuell destruktor delete drawable_ptr; Delete genom basklass-pekare tar bara bort basklass-objekt-delen om inte destruktorn är virtual! Är protected basklass- destruktor en bra ide? adasd dfasfas sfdsfd Box* Cirkel* Pil* Linje* Text_Box* 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
typeid och type_info #include <typeinfo> type_info ti; class Minklass : public Overklass {…} Minklass mittobj; Overklass *minpekare = & mittobj; ti = typeid(*myptr); cout << ti.name() << endl; // Vad händer? 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT
typeid och type_info forts cout << ti << endl; // Vad händer? klass med virtuella funktioner: det av myptr utpekade objektets dynamiska typ skrivs ut, dvs Minklass klass utan virtuella funktioner: den statiska typen hos uttrycket (*myptr) skrivs ut, dvs Basklass typeid funkar på alla slags typer och uttryck: typeinfo(myint), typeinfo(a || b), typeinfo(3.1415) 5/25/2018 CD5250 OOP med C++ Mats Medin MDH/IDT