Innehåll. Typomvandlingar (casting) Implicita Typomvandlingar. Typomvandlingar (casting) Implicita Typomvandlingar

Relevanta dokument
Innehåll. Konstruktorer vid arv Regler för basklassens konstruktor. Konstruktorer vid arv. Konstruktorer vid arv. Konstruktorer vid arv

Innehåll. 1 Kort om dynamisk polymorfism. 2 Arv i C++ 3 Multipelt arv. 4 Något om statisk polymorfism. class Container {

Innehåll. Typomvandlingar (casting) Implicita Typomvandlingar. Typomvandlingar (type casts) Explicita, namngivna typomvandlingar (C++-11)

Programmering i C++ EDA623 Arv. EDA623 (Föreläsning 6) HT / 42

Innehåll. 1 Funktionsmallar. 2 Pekare och konstanter. 3 Typomvandlingar. struct Name { string s; //... };

Innehåll. Pekaren this Självreferens. Klasser Resurshantering, representation. Överlagring av operatorer. Överlagring av operatorer

Innehåll. Pekare Exempel

Innehåll. 1 Typdeklarationer och typomvandling 2 Resurshantering. 3 Objektorientering, kort repetition. 4 Klasser

Innehåll. Pekare Exempel

Innehåll. Användardefinierade typer. Användardefinierade typer Kategorier. Konstruktorer. Konstruktorer Två sätt att skriva initiering av medlemmar

Innehåll. 1 volatile. 2 Kuriositeter. 3 Klasser och arv. 4 Råd och tumregler. 5 Mer om standard-containers. Trigraphs

Introduktion till arv

Programsystem konstruktion med C++ (2D1387) Innehåll. övning 2 klasser och arv

Innehåll. Resurshantering. Resource handles. Minnesallokering. Minnesallokering Exempel: allokering på stacken. 6. Resurshantering

Programmering i C++ EDA623 Objektorienterad programutveckling. EDA623 (Föreläsning 5) HT / 33

Skapa, kopiera och destruera klassobjekt

Klasser. Kapitel 2. Kapitel 2 - Klasser, medlemmar och arv. Klasser. Klasser Medlemmar Arv

Introduktion. Klasser. TDP004 Objektorienterad Programmering Fö 2 Objektorientering grunder

Innehåll. Resource handles. Resurshantering. Minnesallokering. Minnesallokering Exempel: allokering på stacken. 7. Resurshantering, Felhantering

Dynamisk bindning och polymorfism

Programsystemkonstruktion med C++: Övning 2. Karl Palmskog september 2010

TDDC76 - Programmering och Datastrukturer

Del2 Klasser, medlemmar och arv Ämnesområden denna föreläsning:

Arv bakgrund (kap. 9)

Innehåll. Pekare Syntax

Innehåll. Exceptionella händelser (exceptions, undantag ) Felhantering Tre nivåer av felhantering: Nivå 2: exceptions (eller returvärde)

F8: Typkonvertering i C++

Innehåll. 1 Deklarationer, scope och livstid. 2 Användardefinierade typer. 4 Operatoröverlagring. 5 In- och utmatning. 6 namnrymder (namespace)

TDDC76 Programmering och datastrukturer

Innehåll. 1 Deklarationer, scope och livstid. 2 Användardefinierade typer. 4 In- och utmatning. 5 Operatoröverlagring. 6 namnrymder (namespace)

TDIU20 - Objektorienterad programmering i c++ - föreläsning 6

Innehåll. Parametriserade typer. Klassmallar. Klassmallen Vektor Konstructor med std::initializer_list. Klassmallen Vektor Medlemsfunktioner

TDIU01 Programmering i C++

Del3 Klassanvändning, operatorer och pekare Ämnesområden denna föreläsning:

Övriga byggstenar. Övriga byggstenar. Några tips under programutveckling. Beroenden Pekare till funktioner Typkonvertering

DAT043 - Föreläsning 7

TDIU20 - Objektorienterad programmering i c++ - föreläsning 4

allokeras på stacken dynamiskt new delete

5 Arv och dynamisk bindning FIGUR

Minneshantering. Minneshantering. Minneshantering. Undvik pekare

Objektorienterad programmering Föreläsning 12. Copyright Mahmud Al Hakim

Classes och Interfaces, Objects och References, Initialization

TDDC76 - Programmering och Datastrukturer

UML. Klassdiagr. Abstraktion. Relationer. Överskugg. Överlagr. Aktivitetsdiagram Typomv. Typomv. Klassdiagr. Abstraktion. Relationer.

OOP Objekt-orienterad programmering

Programmering i C++ EDA623 Typer. EDA623 (Föreläsning 4) HT / 33

Tentamen i TDP004 Objektorienterad Programmering Lösningsförslag

Innehåll. EDAf30: Programmering i C++, 7.5 hp. EDAf30: Programmering i C++, 7.5 hp Viktiga skillnader mot Java

Objektorientering - Arv och polymorfi. Eric Elfving Institutionen för datavetenskap

Programsystemkonstruktion med C++

TDIU01 - Programmering i C++, grundkurs

Innehåll. 1 Funktionsmalllar. 2 Klassmallar. struct Name { string s; //... }; const Name & minimum ( const Name & a, const Name & b) { if(a.s < b.

TDDC76 - Programmering och Datastrukturer

Objektorientering - Arv och polymorfi

Arv. Objektorienterad och komponentbaserad programmering

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

Idag. Javas datatyper, arrayer, referenssemantik. Arv, polymorfi, typregler, typkonvertering. Tänker inte säga nåt om det som är likadant som i C.

Operatoröverlagring. endast operatorsymboler definierade i C++ kan överlagras = += -= *= /= %= ^= &= = <<= >>= < > <= >= ==!= && > ->*, [ ] ( )

DD2387 Programsystemkonstruktion med C++ Tentamen 1 Torsdag 7 januari 2016, 14:00-18:00

Tillämpad programmering

Tentamen i TDP004 Objektorienterad Programmering Teoretisk del

Static vs Dynamic binding Polymorfism. Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

KLASSER. Inkapsling Abstrakt datatyp Public och private. Klassmedlemmar Datamedlemmar Exempel Funktionsmedlemmar

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Klasshierarkier - repetition

Programmering i C++ EDA623 Mer om klasser. EDA623 (Föreläsning 6) HT / 26

Arv. Fundamental objekt-orienterad teknik. arv i Java modifieraren protected Lägga till och modifiera metoder med hjälp av arv Klass hierarkier

Lektionsuppgifter. TDDI14 Objektorienterad programmering. Lektionsplanering Lektion Lektion Lektion

Classes och Interfaces, Objects och References Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

EDAf30: Programmering i C++, 7.5 hp. EDAf30: Programmering i C++, 7.5 hp Administration. EDAf30: Programmering i C++, 7.5 hp Obligatoriska moment

Kapitel 3. Synlighet. Kapitel 3 - Klassanvändning, operatorer och pekare. Synlighet

TDIU01 - Programmering i C++, grundkurs

OOP Objekt-orienterad programmering

Innehåll. Pekare. Datatyper Pekare, Arrayer och Referenser. Pekare Syntax. Pekare Syntax, operatorer. 4. Standard-containers. Pekare och arrayer

Del2 Klasser, medlemmar och arv Ämnesområden denna föreläsning:

Konstruktion av klasser med klasser

Föreläsning 8. Arv. Arv (forts) Arv och abstrakta klasser

Tillämpad programmering

Synlighet. Namespace Scope-operatorn Klasser Vänner

TDDC76 PoD OH Föreläsning C Härledda klasser

Arv: Fordonsexempel. Arv. Arv: fordonsexempel (forts) Arv: Ett exempel. En klassdefinition class A extends B {... }

Tommy Färnqvist, IDA, Linköpings universitet

Subtyping och variance. Objekt-orienterad programmering och design Alex Gerdes, 2018

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

Nedan skapar vi klassen Person innehållande datamedlemmar för förnamn, efternamn, ålder, längd och vikt:

Tentamen i Objektorienterad Programmering 5p, Au, D, Fri, Pr,

"Är en"-relation. "Har en"-relation. Arv. Seminarium 2 Relevanta uppgifter. I exemplet Boll från förra föreläsningen gällde

public och private Obs: private inte skyddar mot access från andra objekt i samma klass.

F4. programmeringsteknik och Matlab

Grundläggande programmering, STS 1, VT Sven Sandberg. Föreläsning 14

Static vs Dynamic binding Polymorfism. Objekt-orienterad programmering och design Alex Gerdes, 2016

Vad är en klass? Övning 2. Konstruktorer. ffl copy-konstruktorn tar en instans av klassen som. ffl default-konstruktorn tar inga argument och kan

Kapitel 6 - Undantag

Föreläsning 13 Innehåll

Kopiering av objekt i Java

Java, klasser, objekt (Skansholm: Kapitel 2)

Subklasser och arv Inledning till grafik (JFrame och JPanel). Något om interface. Objektorienterad programvaruutveckling GU (DIT011) Subklasser

TDDD78, TDDE30, 729A Typhierarkier del 2 Vad krävs? Hur fungerar det?

DD2387 Programsystemkonstruktion med C++ Tentamen 2

Subtyping, co- och contra-variance. Objekt-orienterad programmering och design Alex Gerdes, 2016

Transkript:

Innehåll EDAF30 Programmering i C++ 9. Polymorfism och arv Sven Gestegård Robertz Datavetenskap, LTH 2016 1 Typomvandling 2 Klasser Polymorfism och arv Konstruktorer och destruktorer Tillgänglighet Arv utan polymorfism Fallgropar 3 Multipelt arv 9. Polymorfism och arv 2/1 Implicita Typomvandlingar Implicita Typomvandlingar Automatiska typomvandlingar Uttryck av typen x y, för någon binär operator E double + int ==> double float + long + char ==> float Tilldelningar och initieringar: Värdet i högerledet konverteras till samma datatyp som i vänsterledet Konvertering av typen hos aktuella parametrar till typen för de formella parametrarna Villkor i if-satser, etc. bool C-array pekare (array decay) 0 nullptr (tom pekare, i C++11, tidigare definierade man ofta konstanten NULL) Automatiska typomvandlingar Uttryck av typen x y, för någon binär operator E double + int ==> double float + long + char ==> float Tilldelningar och initieringar: Värdet i högerledet konverteras till samma datatyp som i vänsterledet Konvertering av typen hos aktuella parametrar till typen för de formella parametrarna Villkor i if-satser, etc. bool C-array pekare (array decay) 0 nullptr (tom pekare, i C++11, tidigare definierade man ofta konstanten NULL) Typomvandling 9. Polymorfism och arv 3/37 Typomvandling 9. Polymorfism och arv 4/37 Explicita, namngivna typomvandlingar (C++-11) static_cast<new_type> (expr) - omvandlar mellan kompatibla typer (kollar inte talområden) reinterpret_cast<new_type> (expr) - inget skyddsnät, samma som C-stil const_cast<new_type> (expr) - lägger till eller tar bort const dynamic_cast<new_type> (expr) - används för pekare till klasser. Gör typkontroll vid run-time, som i Java. char c; int *p = ( int *) &c; // 1 byte // pekar på int : 4 bytes *p = 5; // fel vid exekvering, stack - korruption int *q = static_cast < int *> (&c); // kompileringsfel Typomvandling 9. Polymorfism och arv 5/37 Explicita typomvandlingar, C-stil Syntax i C och i C++, som i Java (typnamn)uttryck, t ex (float) 10 Stor risk att göra fel - använd namgivna typomvandligar blir tydligare i koden, t ex const_cast kan bara ändra const lätt att söka efter: casts är bland det första man tittar på när man letar fel Varning i GCC: -Wold-style-casts Vanlig i äldre kod Alternativ syntax i C++ typnamn ( uttryck ) typnamn måste vara ett ord, d v s int *(...) eller unsigned long(...) är inte OK. Typomvandling 9. Polymorfism och arv 6/37

Varnande exempel Varnande exempel struct Point struct Point3d : Point int z; Point: Point3d: z: struct Point Point ps [3]; struct Point3d int z; Point3d * foo = ( Point3d *) ps; ps: foo[0] foo[1] Med named casts måste man använda reinterpret_cast<point3d*> med static_cast fås felet invalid static_cast from type Point[3] to type Point3d* Typomvandling 9. Polymorfism och arv 7/37 Typomvandling 9. Polymorfism och arv 8/37 specialfall: void-pekare Regler för basklassens konstruktor En void* kan peka på vad som helst (objekt av godtycklig typ.) I C omvandlas void* implicit till/från varje pekartyp. I C++ omvandlas T* implicit till void*. Åt andra hållet krävs en explicit type cast. Basklassens default-konstruktor anropas implicit om den finns! Argument till basklassens konstruktor ges i initierar-listan i subklassens konstruktors. basklassens namn måste används. (super() som i Java finns inte p g a multipelt arv.) Typomvandling 9. Polymorfism och arv 9/37 Klasser : Konstruktorer och destruktorer 9. Polymorfism och arv 10/37 Initieringsordning i en konstruktor (för härledd klass) 1 Basklassen initieras: Basklassens konstruktor anropas 2 Subklassen initieras: Datamedlemmar (i subklassen) initieras 3 Funktionskroppen i subklassens konstruktor exekveras Explicit anrop av basklassens konstruktor i initieringslistan D::D( param...) :B( param...),...... Notera: Konstruktorer ärvs inte Anropa inte virtuella funktioner från en konstruktor.: I basklassen B är this av typen B*. B D Konstruktorer ärvs inte class Base Base (int i) :xi virtual void print () cout << " Base : " << x << endl ; : class Derived : Base void test_ctors () Derived b (5); // no matching function for call to // Derived :: Derived (int) Derived b2; // use of deleted function Derived :: Derived () Klasser : Konstruktorer och destruktorer 9. Polymorfism och arv 11/37 Klasser : Konstruktorer och destruktorer 9. Polymorfism och arv 12/37

using: gör basklassens konstruktor synlig (C++11) class Base Base (int i) :xi virtual void print () cout << " Base : " << x << endl ; : class Derived : Base using Base :: Base ; void test_ctors () Derived b2 (5); // OK! Derived b; // use of deleted function Derived :: Derived () b. print (); Klasser : Konstruktorer och destruktorer 9. Polymorfism och arv 13/37 Nu med default-konstruktor class Base Base (int i=0) :xi virtual void print () cout << " Base : " << x << endl ; : class Derived : Base using Base :: Base ; void test_ctors () Derived b; // OK! b. print (); Derived b2 (5); // OK! b2. print (); Klasser : Konstruktorer och destruktorer 9. Polymorfism och arv 14/37 Ärvda konstruktorer regler Kopiering och arv using gör att alla superklassens konstruktorer ärvs, utom de som döljs av subklassen (har samma parametrar) default- copy- och move-konstruktorer ärvs inte om de inte definieras, syntetiseras de som vanligt default-parametrar i superklassen ger flera ärvda konstruktorer Kopieringskonstruktorn ska kopiera hela objektet typiskt: anropa superklassens kopierings-konstruktor Samma sak gäller för operator= Skillnad mot destruktorn En destruktor i en subklass ska bara avallokera det som allokerats i subklassen. Basklassens destruktor anropas implicit. En subklass kan inte kopieras om superklassen saknar (d v s är eller =delete) default-konstruktor, copy-konstruktor, copy-assignment operator eller destruktor Basklasser bör definiera dessa =default Klasser : Konstruktorer och destruktorer 9. Polymorfism och arv 15/37 Klasser : Konstruktorer och destruktorer 9. Polymorfism och arv 16/37 Destruktorer vid arv Tillgänglighet Destruktorn görs i omvänd ordning: Exekveringsordning i en destruktor 1 Funktionskroppen i subklassens destruktor exekveras 2 Subklassens medlemmar destrueras 3 Basklassens destruktor anropas I basklassen ska destruktorn vara virtuell De olika nivåerna av tillgänglighet class C // Medlemmar å tkomliga från godtyckliga funktioner protected : // Medlemmar å tkomliga från medlemsfunktioner // i klassen eller hä rledda klasser : // Medlemmar å tkomliga endast från // klassens egna medlemsfunktioner Klasser : Konstruktorer och destruktorer 9. Polymorfism och arv 17/37 Klasser : Tillgänglighet 9. Polymorfism och arv 18/37

Tillgänglighet Tillgänglighet Tillgänglighet vid arv Tillgänglighet vid arv class D1 : B // Publikt arv class D2 : protected B // Skyddat arv class D3 : B // Privat arv Tillgänglighet i B Tillgänglighet via D Publikt arv protected protected protected Skyddat arv protected protected Privat arv protected Tillgängligheten inuti D påverkas inte av typen av arv Klasser : Tillgänglighet 9. Polymorfism och arv 19/37 Klasser : Tillgänglighet 9. Polymorfism och arv 20/37 Funktionsöverlagring och arv Funktionsöverlagring fungerar ej som vanligt mellan olika nivåer i arvshierarkin class C1 void f( int ) cout << "C1 ::f( int )\n"; class C2 : C1 void f (); cout << "C2 ::f( void )\n"; C1 a; C2 b; a.f (5); // Ok, anropar C1 ::f( int ) b.f (); // Ok, anropar C2 ::f( void ) b.f (2) // Fel! C1 ::f är dold! b.c1 ::f (10); // Ok Funktionsöverlagring och arv Gör namn i superklass synliga med using Funktionsöverlagring mellan olika nivåer i arvshierarkin class C1 void f( int ); cout << "C1 ::f(int )\n"; class C2 : C1 using C1 ::f; void f(); cout << "C2 ::f( void )\n"; C1 a; C2 b; a.f (5); // Ok, anropar C1 ::f(int) b.f(); // Ok, anropar C2 ::f( void ) b.f(2) // Ok, anropar C1 ::f(int) Klasser : Tillgänglighet 9. Polymorfism och arv 21/37 Klasser : Tillgänglighet 9. Polymorfism och arv 22/37 Arv och scope Arv utan virtuella funktioner En subklass scope är kapslat (eng: nested) inuti superklassens Namn i superklassen syns i subklasser om de inte döljs av samma namn i subklassen Använd scope-operatorn :: för att komma åt dolda namn Namnuppslagning sker vid kompilering Statisk typ för en pekare eller referens styr vilka namn som syns (som i Java) Virtuella funktioner måste ha samma parametertyper i subklasser I C++ är medlemsfunktioner inte virtuella om det inte anges. (Skillnad från Java) Man kan ärva från en klass och dölja dess funktioner. Man kan explicit anropa funktioner i superklassen. Kan användas för att utöka en funktion. (Lägga till saker före och efter funktionen.) Klasser : Tillgänglighet 9. Polymorfism och arv 23/37 Klasser : Arv utan polymorfism 9. Polymorfism och arv 24/37

Arv utan virtuella funktioner Fallgropar struct Clock Clock (int h, int m, int s) : seconds 60*(60* h+m) + s Clock & tick (); // OBS! Inte virtuell int get_ticks () return seconds ; : int seconds ; struct AlarmClock : Clock using Clock :: Clock ; void setalarm ( int h, int m, int s); AlarmClock & tick (); // dö ljer Clock :: tick () void soundalarm (); : int alarmtime ; Typomvandling Tilldelning eller kopiering av objekt av konkreta typer AlarmClock & AlarmClock :: tick () Clock :: tick (); // explicit anrop av funktion i superklassen if( get_ticks () == alarmtime ) soundalarm (); return * this ; Klasser : Arv utan polymorfism 9. Polymorfism och arv 25/37 Klasser : Fallgropar 9. Polymorfism och arv 26/37 Typomvandling Object slicing Se upp med typomvandlingar Framför allt (Subklass*) BasklassPekare Inget skyddsnät, ingen ClassCastException Använd dynamic_cast (returnerar nullptr om ej OK) Vektor v; Container * c = &v; if( dynamic_cast < Vektor *>(c)) cout << " *c instanceof Vektor \n"; typeid motsvarar.getclass() i Java if(typeid (*c) == typeid ( Vektor )) cout << " *c is a Vektor \n"; class Point... class Point3d : Point... Point3d b; Point a = b; Inte farligt, men a innehåller bara Point-delen av b Point3d b1; Point3d b2; Point & point_ref = b2; point_ref = b1; Fel! b2 innehåller nu Point-delen av b1 och Point3d-delen av sitt gamla värde. Klasser : Fallgropar 9. Polymorfism och arv 27/37 Klasser : Fallgropar 9. Polymorfism och arv 28/37 Object slicing struct Point Point (int xi, int yi) :xxi, yyi virtual void print () const ; // prints Point (x,y) struct Point3d : Point Point3d (int xi, int yi, int zi) : Point (xi,yi), zzi virtual void print () const ; // prints Point3d (x,y,z) int z; void test_slicing () Point3d q1 1,2,3 Point3d q2 3,4,5 q2. print (); Point3d(3,4,5) Point & pr = q2; pr = q1; q2. print (); Point3d(1,2,5) Lösning: virtuell operator= Klasser : Fallgropar 9. Polymorfism och arv 29/37 Object slicing Lösning med virtuell operator= struct Point... virtual Point & operator =( const Point & p) = default ; struct Point3d : Point... virtual Point3d & operator =( const Point & p) noexcept ; Point3d & Point3d :: operator =( const Point & p) noexcept Point :: operator =(p); auto p3d = dynamic_cast < const Point3d * >(&p); if(p3d ) z = p3d ->z; else z = 0; return * this ; Klasser : Fallgropar 9. Polymorfism och arv 30/37

Multipelt arv En klass kan ärva från flera basklasser Jfr. implementera flera interface i Java Som i Java om max en av basklasserna har medlemsvariabler Kan bli besvärligt annars The diamond problem Hur många MotorVehicle ingår i en MiniBus? MotorVehicle Multipelt arv Hur många MotorVehicle ingår i en MiniBus? class MotorVehicle... class Bus : MotorVehicle... class Car : MotorVehicle... class MiniBus : Bus, Car... MotorVehicle Bus Car Bus MiniBus Car MiniBus string Bus::regno; int Bus::weight; string Car::regno; int Car::weight; Multipelt arv 9. Polymorfism och arv 31/37 Multipelt arv 9. Polymorfism och arv 32/37 Multipelt arv The diamond problem Multipelt arv Virtuellt arv Virtuellt arv : Subklasser delar instans av basklassen. (Basklassen tas bara med en gång) Den gemensamma basklassen tas med flera gånger Flera upplagor av medlemsvariabler Medlemsfunktioner måste användas som Basklass::funktion() för att undvika tvetydighet om inte virtuellt arv används class MotorVehicle... class Bus : virtual MotorVehicle... class Car : virtual MotorVehicle... class MiniBus : Bus, Car... MotorVehicle Bus Car MiniBus Multipelt arv 9. Polymorfism och arv 33/37 Multipelt arv 9. Polymorfism och arv 34/37 Läsanvisningar Referenser till relaterade avsnitt i Lippman Dynamisk poymorfism och arv kapitel 15 15.4 Tillgänglighet och scope kapitel 15.5 15.6 Typomvandling och arv kapitel 15.2.3 Arv och resurshantering 15.7 Polymorfa typer och containers 15.8 Multipelt arv 18.3 Virtuella basklasser 18.3.4 18.3.5 Multipelt arv 9. Polymorfism och arv 36/37