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

Relevanta dokument
Programsystemkonstruktion med C++

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

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

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

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

TDDC76 - Programmering och Datastrukturer

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

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

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

Innehåll. Pekare Exempel

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

Dynamisk bindning och polymorfism

Innehåll. Pekare Exempel

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

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

TDDC76 - Programmering och Datastrukturer

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

Introduktion till arv

5 Arv och dynamisk bindning FIGUR

Tillämpad programmering

allokeras på stacken dynamiskt new delete

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

Minneshantering. Minneshantering. Minneshantering. Undvik pekare

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

C++ Objektorientering - Klasser. Eric Elfving

C++ Objektorientering - Klasser. Eric Elfving Institutionen för datavetenskap

TDIU01 Programmering i C++

Arv bakgrund (kap. 9)

Classes och Interfaces, Objects och References, Initialization

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

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

Det finns många flaggor till g++,

TDIU01 - Programmering i C++, grundkurs

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

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

TDDC76 Programmering och datastrukturer

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

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

2D1387, Programsystemkonstruktion med C++ Johnny Bigert, Kursens hemsida:

Det objektorienterade synsättet. Objekt. Datorprogrammet kan uppfattas som en slags modell av den verklighet programmet skall samverka med.

grundläggande C++, funktioner m.m.

1 Klasser och objektorientering Vad är objektorientering?

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

Tentamen i TDP004 Objektorienterad Programmering Lösningsförslag

Outline. Objektorienterad Programmering (TDDC77) Att instansiera en klass. Objekt. Instansiering. Åtkomst. Abstrakt datatyp.

Föreläsning 5-6 Innehåll. Exempel på program med objekt. Exempel: kvadratobjekt. Objekt. Skapa och använda objekt Skriva egna klasser

Övningar Dag 2 En första klass

Föreläsning 5-6 Innehåll

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

Synlighet. Namespace Scope-operatorn Klasser Vänner

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

Objektorienterad Programmering (TDDC77)

Föreläsning 8 - del 2: Objektorienterad programmering - avancerat

Första exemplet. Kompilator & länkare. Projekt. Övning 1, Ögrupp 4, Programsystemkonstruktion med C++, Ronnie Johansson,

TENTAMEN CD5250. Objektorienterad programutveckling med C++, 5p. Datum: , Tid: 14:00-19:00

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

OOP Objekt-orienterad programmering

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

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

Tommy Färnqvist, IDA, Linköpings universitet

Objektorienterade programmeringsspråk. Objektorienterade språk. Den objekt-orienterade modellen. Jämför med icke-oo

DD2387 Programsystemkonstruktion med C++ Tentamen 2

Uppgiften är att beskriva en kvadrat i ett Java program. En första version av programmet skulle kunna se ut så här:

Collections Collections "Envisa" objekt Klasserna Bofstream och Bifstream Definition av metoder i klasserna Bifstream och Bofstream Klassen Streng

Generiska konstruktioner. Kursbokens kapitel 13

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

Inledande programmering med C# (1DV402) Tärningarna ska kastas

1 Namnkontroll (NameControl)

TDDC76 - Programmering och Datastrukturer

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

Ett enkelt program i C++, hello.cpp. #include <iostream> int main() { std::cout << "Hello World\n"; return 0; } C++, Övning 1

Objektorienterad Programmering (OOP) Murach s: kap 12-16

Exempel: Exempel: Exempel: Exempel: $djur=array("ko","katt","älg"); foreach ($djur as $d) { echo $d. " "; } Resultat. ko katt älg

TDDE10 TDDE11, 725G90/1. Objektorienterad programmering i Java, Föreläsning 2 Erik Nilsson, Institutionen för Datavetenskap, LiU

Målen med OOSU. Objektorienterad programmering. Objektorienterad programmering. Karlstads Universitet, Johan Öfverberg 1

Vad är en mall och vilka är dess egenskaper? Övning 3. En funktionsmall

Dagens program. Programmeringsteknik och Matlab. Objektorienterad programmering. Vad är vitsen med att ha både metoder och data i objekten?

Föreläsning 4. Klass. Klassdeklaration. Klasser Och Objekt

OOP Objekt-orienterad programmering

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

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

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

Tentamen i TDP004 Objektorienterad Programmering Lösningsförslag

TDDD78 Objektorientering: Lagring och livstid

Teoretisk del. Facit Tentamen TDDC (6)

TDIU01 - Programmering i C++, grundkurs

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

Klasshierarkier - repetition

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

Föreläsning 5 (6) Metoder. Metoder Deklarera. Metoder. Parametrar Returvärden Överlagring Konstruktorer Statiska metoder tostring() metoden javadoc

Programmering B med Visual C

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

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

Innehåll. Introduktion till objektorientering. OOP (objektorienterad programmering) Objekt, instanser, klasser

Idag. statiska metoder och variabler. private/public/protected. final, abstrakta klasser, gränssnitt, delegering. wrapper classes

Kapitel 6 - Undantag

Enkla variabler kontra referensvariabel

F8 - Arv. ID1004 Objektorienterad programmering Fredrik Kilander

LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p

Tentamen EDAF30 Programmering i C++

Transkript:

Vad är en klass? Övnin 2 Daens ämne är klasser och hur de hanteras. Vi kommer att bya upp ett exempel stevis och illustrera en hel del möjliheter, men också problem och saker man bör vara vaksam på. ffl En klass bör fåna ett koncept. Animal () : name ( "no name" ) f Animal ( char Λ n ) : name ( n ) f ffl En klass kan inå ienklasshierarki och specialisera eenskaper hos basklasserna. class Man : Animal f class XMan : Man f Konstruktorer Konstruktorer initierar ett minnesutrymme så att det representerar en instans av en klass. ffl default-konstruktorn tar ina arument och kan se ut på tvåsätt: Animal(); Animal(std::strin name = ""); Den svarar mot ett oinitialiserat objekt, tex ett namnlöst djur. Det år att beränsa användninen av en konstruktor enom att deklarera den protected eller private. ffl copy-konstruktorn tar en instans av klassen som parameter och skapar en kopia. class Anthill f Anthill ( char Λ ascii_pic ) f pic = new char [ strlen ( ascii_pic ) +1]; strcpy ( pic, ascii_pic ); Anthill ( const Anthill &ah ) f pic = new char [ strlen ( ah. pic )+1]; strcpy ( pic, ah. pic ); Anthill () f delete [] pic ; char Λ pic ; Det är ofta nödvändit för klasser som har pekare som medlemmar. Copy-konstruktorn ersätter memberwise initialization, vilket annars sker automatiskt.

När allokeras på stack respektive heap? ffl ytterliare konstruktorer tar en eller flera parametrar och initierar instansen med dessa. Animal () : name ( "no name" ) f Animal ( char Λ n ) : name ( n ) f cout << "Animal()" << endl ; Ofta finns det ett antal olika konstruktorer för olika ändamål. Nåra av dessa kan vara deklarerade protected och endast avsedda för underklasser. Det finns två typer av allokerin. ffl Stacken: allokerin och deallokerin sker automatiskt för temporära variabler. int foo(int i) { int x; Animal a("fido");... return 0; } Vid anropet till foo skapas ett utrymme påstacken för i, x och a. Sedan körs konstruktorn i klassen Animal för att initiera a. Vid return körs destruktorn för a och sedan betraktas det allokerade utrymmet som fritt att använda. Utrymmet kan fysiskt innehålla samma information, men det kan skrivas över i vilket öonblick som helst. ffl Heapen: prorammeraren tar över ansvaret för deallokerin. Animal* bar(int size) { Animal *a = new Animal("Fido"); int *x = new int[size];... delete [] x; return a; } Till skillnad från stacken kan objekt på heapen överleva funktionsanrop. Det är nåot lånsammare att allokera på heapen, men framför allt så är det mycket lätt att öra fel och få minnesläckor. Var noranna vid allokerin på heapen och fundera på hur ni ska deallokera objekt som ni allokerar på heapen. Vad händer när... en instans skapas: 1. Allokera ett minnesutrymme som är stort no för objektet på stacken eller på heapen. 2. Kör konstruktor för superklass. 3. Kör konstruktorer för medlemsvariabler. 4. Kör konstruktorn....eller raderas: 1. Kör destruktorn. 2. Kör destruktorn för medlemsvariabler. 3. Kör destruktorn för superklass. 4. Deallokera minnesutrymmet.

Varför en initierinslista? ffl const respektive referens deklarerade medlemmar måste initieras i initierinslistan. Varför? class Ant : public Animal f Ant ( char Λ n, Anthill &ah, const bool b ) : Animal ( n ), anthill ( ah ), worker ( b ) f // anthill = ah ; // ERROR! // worker = b ; // ERROR! const bool worker ; Anthill &anthill ; ffl Initierinslistan är ofta effektivare då den undviker exekverin av en defaultkonstruktor. Animal ( char Λ n ) : name ( n ) f Använd initierinslistan om det år! Heap-allokerin i klass och Destruktorn En klass behöver ofta allokera minne på heapen internt. Detta örs i konstruktorn och destruktorn deallokerar sedan minnet. class Anthill f Anthill ( char Λ ascii_pic ) f pic = new char [ strlen ( ascii_pic ) +1]; strcpy ( pic, ascii_pic ); Anthill () f delete [] pic ; char Λ pic ; Om vi nu stack-allokerar ett Anthill-objekt så behöver vi inte bry oss om deallokerinen, för det har vi redan löst en ån för alla!! int foo () f Det är prorammerarens ansvar att deallokera!

Åtkomstberänsnin Det finns tre nivåer för åtkomst till medlemmar i en klass. ffl public er alla tillån till medlemmarna. ffl protected er deriverade klasser tillån till medlemmarna. ffl private beränsar tillånen till klassen själv. protected : friend ostream& operator<<(ostream&, Animal &); Vid arv kan åtkomstberänsninen stärkas, men inte försvaas. class A f class B : public A f class C : protected A f class D1 : private A f class D2 : A f En klass kan bjuda in en speciell funktion eller klass att få tillån till dess medlemmar enom att deklarera den friend. Arv: konstruktorer Animal ( char Λ n ) : name ( n ) f cout << "Animal()" << endl ; virtual Animal () f cout << " Animal()" << endl ; class Man : public virtual Animal f Man ( char Λ n ) : Animal ( n ) f cout << "Man()" << endl ; Man () f cout << " Man()" << endl ; class XMan : public Man f XMan ( char Λ n ) : Animal ( n ), Man ( n ) f cout << "XMan()" << endl ; XMan () f cout << " XMan()" << endl ; XMan x ( "Maneto" ); Detta er vid körnin $./example1 Animal() Man() XMan() XMan() Man() Animal()

Arv: multipelt arv Vi blandar myra med människa :-) ; class Ant : public virtual Animal f Ant ( char Λ n, Anthill &ah, const bool b ) : Animal ( n ), anthill ( ah ), worker ( b ) f char Λ draw () f return "\\o/\n" "-o-\n" "/O\\\n" ; const bool worker ; Anthill &anthill ; class Man : public virtual Animal f Man ( char Λ n ) : Animal ( n ) f char Λ draw () f return " o \n" "- -\n" " /\\ \n" ; class Monster : public Man, public Ant f Monster ( char Λ n, Anthill &ah ) : Animal ( n ), Man ( n ), Ant ( n, ah, false ) f Utan virtual blir det två kopior av Animal som måste åtskiljas vid anrop. Monster m ( Monstermannen, ah ); m. Man ::draw (); Nyckelordet virtual ör att: ffl det bara skapas en kopia av superklassen Animal. ffl den understa underklassen måste själv initiera Animal. (detta är inte tillåtet i annat fall) Polymorphism Betrakta raderna: virtual char Λ isa () f return "Animal" ; class Ant : public virtual Animal f char Λ isa () f return "Ant" ; class Man : public virtual Animal f char Λ isa () f return "Man" ; class XMan : public Man f char Λ isa () f return "XMan" ; class Monster : public Man, public Ant f char Λ isa () f return "Monster" ; En av fördelarna med objektorienterin är att man kan öra följande: Animal Λ ani [4]; ani [0] = new Ant ( "Lars", ah, true ); ani [1] = new Man ( "Stefan" ); ani [2] = new XMan ( "Maneto" ); ani [3] = new Monster ( "Antman", ah ); for ( int i = 0; i < 4; i++) f cout << Λani [ i] << " is a " << ani [ i] >isa () << endl ; for ( int i = 0; i < 4; i++) f delete ani [ i ];

ffl Notera att Animal::isa() är deklarerad virtual. ffl Kompilatorn håller i en tabell reda på vilken class en instans tillhör eentlien. Vid anrop örs ett uppsla i tabellen. Detta funerar med både pekare och med referenser, men inte med vanlia variabler. ffl Viktit: Om vi inte hade Animal:: Animal() som virtual så hade vi råkat ut för en minnesläcka med koden ovanför. Varför? Destruktorer i basklasser ska vara virtual! ffl IJavaär alla klassfunktioner motsvariheten till virtual om inet speciellt örs. I java kan man använda nyckelordet final för att häva detta och framtvina statisk länknin. Abstrakta basklasser Animal borde vara en abstrakt klass som aldri själv instansieras, men som beskriver emensamma attribut hos alla djur. Det är tex oklart vad Animal::isa() ska returnera. Ett alternativ är att definiera: virtual char Λ isa () = 0; Det innebär att det inte år att instansiera Animal, samt att varje underklass U måste definiera en funktion U::isa(). DvsAnimal blir abstrakt. Animal::isa() kallas nu en strikt virtuell funktion. Static-variabler och medlemmar Anta att vi vill hålla koll på hur måna myror det finns vid varje tillfälle. Ett naturlit sätt att öra det är följande. class Ant : public virtual Animal f static int et_no_ants () f return no_ants ; Ant ( char Λ n, Anthill &ah, const bool b ) : Animal ( n ), anthill ( ah ), worker ( b ) f Ant ::no_ants++; Ant () f Ant ::no_ants ; static int no_ants ; const bool worker ; Anthill &anthill ; // Next line can not be i. h file, WHY? // It must appear exactly once. int Ant ::no_ants = 0; Stroustrup säer: Operatoröverlarin It s hard to overestimate the importance of concise notation for common types.. Av detta skäl så kanmanic++överlara inte bara alla vanlia funktioner utan även inbyda funktioner som tex +,-,*,++ osv Ivårt exempel överlarade vi << operatorn. Ett bra tillfälle att överlara operatorer är när man implementerar aritmetik med komplexa tal tex. Då är det trevlit att kunna skriva: Complex a (1,2); Complex b (4,5); Complex c ; c = a + b ;

Hela exemplet Två varninar ffl Använd operatoröverlarin endast då detär fullt naturlit! Alla dataloer tycker inte som Stroustrup. ffl Använd multipelt arv ytterst sparsmakat.det är lätt att öra fel, och det finns ofta alternativa sätt att lösa problem på somär bättre. Måna tycker att multipelt arv är en styelse. En snyare lösnin av problemet återfinns i Java där man infört bereppet interface. En klass får bara ärva en klass, men kan implementsera hur måna interface som helst. Fil 1: someclasses.h #ifndef SOMECLASSES #define SOMECLASSES #include <iostream> #include <stdlib. h> #include <strin> friend ostream& operator<<(ostream&, Animal &); Animal () : name ( "no name" ) f Animal ( char Λ n ) : name ( n ) f cout << "Animal()" << endl ; virtual Animal () f cout << " Animal()" << endl ; virtual char Λ isa () = 0; class Anthill f friend ostream& operator<<(ostream &os, Anthill &a ); Anthill ( char Λ ascii_pic ) f pic = new char [ strlen ( ascii_pic ) +1]; strcpy ( pic, ascii_pic ); cout << "Anthill() allocates" << endl ; Anthill ( const Anthill &ah ) f pic = new char [ strlen ( ah. pic )+1]; strcpy ( pic, ah. pic ); Anthill () f delete [] pic ; cout << " Anthill() deallocates\n" ; char Λ pic ; class Ant : public virtual Animal f static int et_no_ants () f return no_ants ; Ant ( char Λ n, Anthill &ah, const bool b ) : Animal ( n ), anthill ( ah ), worker ( b ) f cout << "Ant()" << endl ; Ant ::no_ants++; Ant () f cout << " Ant()" << endl ; Ant ::no_ants ; char Λ isa () f return "Ant" ; char Λ draw () f cout << "\\o/\n" "-o-\n"

"/O\\\n" ; static int no_ants ; const bool worker ; Anthill &anthill ; class Man : public virtual Animal f Man ( char Λ n ) : Animal ( n ) f cout << "Man()" << endl ; Man () f cout << " Man()" << endl ; char Λ isa () f char Λ draw () f cout << " o \n" "-U-\n" " /\\ \n" ; return "Man" ; class XMan : public Man f XMan ( char Λ n ) : Animal ( n ), Man ( n ) f cout << "XMan()" << endl ; XMan () f char Λ isa () f cout << " XMan()" << endl ; return "XMan" ; class Monster : public Man, public Ant f Monster ( char Λ n, Anthill &ah ) : Animal ( n ), Man ( n ), Ant ( n, ah, false ) f cout << "Monster()" << endl ; Monster () f cout << " Monster()" << endl ; char Λ isa () f return "Monster" ; #endif // SOMECLASSES Fil 2: someclasses.cpp ostream& operator<<(ostream & os, Animal &a ) f os << a. name ; return os ; ostream& operator<<(ostream & os, Anthill &ah ) f os << ah. pic ; return os ; int Ant ::no_ants = 0; Fil 3: example1.cpp int main () f XMan x ( "Maneto" ); Fil 4: example2.cpp " xxxxxxxxxxxxxxxxx" ); cout << "\na nice anthill:\n" << ah << endl << endl ; Fil 5: example3.cpp

Monster m ( "Monstermannen", ah ); m. Man ::draw (); m. Ant ::draw (); Fil 6: example4.cpp Ant a1 ( "Mats", ah, true ); Ant a2 ( "Lars", ah, true ); Ant a3 ( "Ulrika", ah, true ); Ant a4 ( "Anna", ah, true ); cout << "Number of ants is: " << Ant ::et_no_ants () << endl ; Fil 7: example5.cpp Animal Λ ani [4]; ani [0] = new Ant ( "Lars", ah, true ); ani [1] = new Man ( "Stefan" ); ani [2] = new XMan ( "Maneto" ); ani [3] = new Monster ( "Antman", ah ); for ( int i = 0; i < 4; i++) f cout << Λani [ i] << " is a " << ani [ i] >isa () << endl ; for ( int i = 0; i < 4; i++) f delete ani [ i ];