Operatorer för medlemspekare

Storlek: px
Starta visningen från sidan:

Download "Operatorer för medlemspekare"

Transkript

1 Medlemspekare Ibland uppstår behovet att peka ut en viss medlem, som skall behandlas i olika objekt. C++ har begreppet medlemspekare (pointer to member) för sådana situationer (har ingen motsvarighet i Java). En medlemspekare är implementerad som ett offset in i ett objekt till den aktuella medlemmen (hur långt från objektets början medlemmen ligger). För att ge en viss medlem i ett visst objekt måste den kompletteras med ett objekt (namn eller referens) eller en pekare till ett objekt. Medlemspekare till medlemsfunktioner är mest användbara, men först lite synatx. Exempel: antag deklarationerna struct Strukt{ int x, y; ; Strukt vek[10]={{2,3, {5, 17, {3, 8, ; Antag att vi vill kunna summera ibland alla x i vek, ibland alla y: int Strukt::*mpek; // Deklaration av medlemspekare till en int i Strukt if (summera x) mpek=&strukt::x; // Medlemsadress -tagning else mpek=&strukt::y; int sum=0; for(int i=0; i<10; i++) sum += vek[i].*mpek; // Åtkomst via medlemspekaren Bild 121 Operatorer för medlemspekare C++ inför tre nya operatorer för medlemspekare och en notation för medlemsadress -tagning: ::* - deklarator för medlemspekare, t.ex. int Strukt::*mpek; Obs alltså att medlemmarnas typ och klassens namn ingår. Medlemsadress - tagning - Adressen till en medlem fås genom notationen mpek=&strukt::x; Obs dock att det är en specialkonstruktion, i själva verket står en medlemspekare för ett offset, inte för en adress. Detta offset måste kombineras med en pekare till ett objekt eller med ett objekt (eller en referens till ett objekt) ->* - åtkomst till en medlem via medlemspekare hos ett objekt som pekas ut av en objektpekare, t.ex. int i=pek->*mpek;.* - åtkomst till en medlem via medlemspekare hos ett objekt (eller en objektreferens), t.ex.: Strukt obj={5, 7; int i=obj.*mpeki; Bild 122 1

2 Pekare till medlemsfunktioner Exempel: class Valued{ int value; Valued():value(0){ void add(int v){value+=v; void sub(int v){value-=v; void mult(int v) {value*=v; ; Valued values[10]; void (Valued::*mfunk)(int i); //Pekare till medlemsfunktion cout << Operation värde: char perator; int perand; cin >> perator >> perand; switch(perator){ case + : mfunk=&valued::add; break; case - : mfunk=&valued::sub; break; case * : mfunk=&valued::mult; break; for(valued *pek=values; pek<values+10; pek++) (pek->*mfunk)(perand); Bild 123 Mer om medlemsfunktionspekare Medlemsfunktionspekare kan t.ex. läggas i datastrukturer som objekt, map<>, arrayer: void (Valued::*mfarr[3])(int) = {&Valued::add, &Valued::sub, &Valued::mult; Varvid både objektet och operationen kan indexeras: (values[5].*mfarr[1])(3); // Anropar values[f].sub(3); Definitionen av arrayen kan förenklas med typedef: typedef void (Valued::*Valfunk)(int); Valfunk mfarr[3]={&valued::add, &Valued::sub, &Valued::mult; Oftast görs sådana typnamndefinitionen i klassen varvid klassnamnet syns i arraydefinitionen: class Valued{ typedef void (Valued::*Mfunk)(int); ; Valued::Mfunk mfarr[3]={&valued::add,&valued::sub,&valued::mult; Bild 124 2

3 Användning av medlemsfunktionspekare Den viktigaste användningen av medlemsfunktionspekare är för sammankoppling av bibliotekskomponenter med medlemsfunktioner i en tillämpnings objekt. Jämför med Javas grafiska komponenter: man installerar s.k. lyssnare som måste ha metoder med föreskriven signatur (namn och argumenttyper), t.ex. void actionperformed(actionevent); Om tillämpningens objekt behöver reagera olika på olika händelser av denna typ och behöver ha flera sådana metoder tvingas man införa nya klasser (oftast inre klasser; s.k. lyssnarklasser) eftersom en klass inte kan ha flera metoder med samma signatur. I C++ med användning av medlemsfunktionspekare kan man skapa direkta kopplingar mellan bibliotekskomponenter och olika medlemsfunktioner i objekt av en tillämpningsklass, dessa medlemsfunktioner behöver inte ha något föreskrivet namn. Eftersom deklarationen av en medlemspekare måste innehålla namnet på tillämpningens klass där medlemsfunktionen ingår måste en sådan koppling i ett bibliotek göras som en mall. Vi återkommer till hur detta görs. Bild 125 Orientering om undantagshantering Undantagshantering i C++ liknar mycket Javas, som lånat mekanismen och syntaxen från C++. Den är dock inte lika genomgripande som i Java - bl.a. kunde man inte införa run-time-kontroller p.g.a. kravet på kompatibilitet med C. Undantag genereras av biblioteket och run-time-systemet endast i ett fåtal fall, indexering utanför arraygränser eller avreferering av null-pekare ger inga undantag utan eventuellt ett vanligt exekveringsavbrott ( Segmentation fault ). Viktigaste skillnader mot Java: egna undantagsklasser används (dock finns en liten bibliotekshierarki) vid throw används inte new, man skapar temporära objekt vid catch behöver inte argumentet namnges argumenttypen till catch bör deklareras som referens att fånga alla undantag görs med catch() det finns ingen motsvarighet till finally undantagsspecifikationer är inte obligatoriska i en undantagshanterare kan throw skrivas utan argument, innebär att samma undantag skickas vidare (re-throw) Bild 126 3

4 Standardbibliotekets undantagshieraki Felaktiga argumentvärden m.m., programmeringsfel logic_error exception Andra fel som upptäcks under exekveringen runtime_error length_error out_of_range bad_alloc bad_exception domain_error invalid_argument bad_cast ios_base::failure range_error overflow_error underflow_error Klasserna exception och bad_exception finns i headerfilen <exception>, de flesta andra i <stdexcept>, men ios_base::failure i <ios> Bild 127 Standardbibliotekets undantagshieraki, forts. I klassen exception deklareras virtual const char *what() const; som subklasserna är tänkta att överskugga för att returnera en C-sträng med ett meddelande som kan skrivas ut. Konstruktorerna i logic_error och runtime_error kräver en sträng (std::string) med ett meddelande som kommer att lagras i undantagsobjektet för att returneras vid efterföljande what()-anrop. length_error en längdangivelse skulle överskrida max domain_error värde av fel matematisk domän out_of_range värde utanför tillåtet intervall (t.ex. vid indexering) invalid_argument otillåtet funktionsargument bad_alloc inget minne vid dynamisk allokering bad_exception odeklarerat undantag från en funktion (se nästa bild) bad_cast misslyckad dynamic_cast för referens ios_base::failure misslyckad iostream-operation (måste begäras) range_error intervallfel i interna beräkningar overflow_error aritmetiskt overflow underflow_error aritmetiskt underflow Bild 128 4

5 Undantag: syntaktiskt exempel #include <stdexcept> class Text{ int size; char *cptr; char& operator[](int index){ if (index < 0 index >= size) throw std::out_of_range( Text index error ); return cptr[index]; ; #include Text.h #include <iostream> using namespace std; int main(){ Text t( Eberhart von Ostenbrink ); try{ cout << Vilken position: ; int pos; cin >> pos; cout << t[pos]; catch(out_of_range& oor){ cerr << Fel: << oor.what() << endl; Bild 129 Ofångna undantag Om ett ofånget undantag når main() (och inte fångas upp där heller) anropas funktionen std::terminate() som avbryter programmet genom att anropa abort() Man kan sätta en egen termineringsfunktion (argumentlös funktion med void som returtyp, (void (*)())) med std::set_terminate(void (*handler)()). En termineringsfunktion förväntas avbryta programmet (annars anropas abort() ändå). Bild 130 5

6 Undantagsspecifikationer En funktion eller konstruktor kan deklarera att den kan generera vissa undantag: void funk(string str,int i) throw(bad_alloc, range_error); Undantagsspecifikationer är en del av funktionens signatur och måste upprepas i definitionen (om man har både en deklaration och en definition). Eftersom undantagsspecifikationer lades till C++ när språket redan användes kunde man inte göra undantagsspecifikationer obligatoriska. Istället är det så att en funktion utan undantagsspecifikation kan generera alla undantag. För att deklarera att en funktion inte tänks generera några undantag skriver man: void funk(string str, int i) throw(); Om en funktion med en undantagsspecifikation genererar ett odeklarerat undantag sker ett anrop till std::unexpected() som i sin tur anropar std::terminate(). Om funktionen innehåller bad_exception i sin undantagsspecifikation genereras istället detta undantag. Dessutom kan man sätta en egen funktion (void (*)()) som unexpected genom anrop till std::set_unexpected(void (*handler)()). Bild 131 Undantagshierarkier Liksom i Java brukar man samla undantag som hör ihop i en klasshierarki: #include <stdexcept> struct Stack_error:public std::length_error{ Stack_error(const std::string& msg):std::length_error(msg){ ; struct Stack_full:public Stack_error{ Stack_full(const std::string& msg):stack_error(msg){ ; struct Stack_empty:public Stack_error{ Stack_empty(const std::string& msg):stack_error(msg){ ; class Stack{ int data[100]; int count; Stack():count(0){ void push(int value) throw(stack_full){ if (count == 100) throw Stack_full("Stack full"); data[count++]=value; int pop() throw(stack_empty){ if (count == 0) throw Stack_empty("Stack empty"); return data[--count]; Bild 132 ; 6

7 Undantagshierarkier Vad man uppnår genom att gruppera undantagen är att tillämpningar kan fånga undantagen med basklassnamnet (om de inte är intresserade av vilket specifikt undantag som genererades). Motsvarande gäller undantagsspecifikationer. Liksom i Java undersöks catch-fraserna uppifrån och ner, vill man ha en speciell hantering av ett visst undantag och mer generell hantering av övriga undantag så måste de specifika undantagstyperna stå först: Stack stack; try{ for(int i=0; i<x; i++) stack.push(i); for(int i=0; i<y; i++) cout << stack.pop(); catch(stack_full&){ cerr << För många tal! << endl; catch(stack_error&){ cerr << Fel vid stackhantering! << endl; catch(length_error&){ cerr << För mycket eller för lite av något! << endl; catch(){ cerr << Ett fel har inträffat! << endl; Bild 133 Resurshantering vid risk för undantag m.m. Viktigt att komma ihåg är att det inte finns någon automatisk garbage collection i C++. Detta gör att om en funktion allokerar minne dynamiskt i början med avsikt att friställa minnet i slutet, men kan avbrytas däremellan av undantag så sker ett minnesläckage. Även i andra sammanhang (öppna / stänga filer o.s.v.) kan det hända att en avslutningsoperation inte utförs vid undantag. Ett bra sätt att undvika detta är att resursanskaffning sker i konstruktorn till ett lokalt objekt och återlämnande sker i objektets destruktor. Vid eventuellt undantag städas objektet bort, dess destruktor anropas och kan städa efter anropet. Speciellt för minnesallokering kan stdandardbibliotekets auto_ptr<> från headerfilen <memory> användas istället för pekare: void funk() throw(bad_alloc, range_error) {. auto_ptr<person> pers(new Person( Ulrika )); Bild 134 7

8 Undantag och konstruktorer/destruktorer En konstruktor som upptäcker sådana fel i sina argumentvärden att den inte kan konstruera ett meningsfullt objekt kan inte göra annat än generera ett undantag: // Rational.h #include <stdexcept> class Rational{ int num, den; explicit Rational(int n=0, int den=1) throw(std::invalid_argument); // Rational.cpp #include Rational.h using namespace std; Rational::Rational(int n, int d) throw(invalid_argument):num(n), den(d){ if (d == 0) throw invalid_argument( Rational: zero denominator! ); reduce(num, den); En destruktor å andra sidan får inte generera undantag det kan hända att den är anropad under uppstädning av stacken pga ett annat undantag. Om detta inträffar anropas terminate()-funktionen. Bild 135 Deklarationsvidder Namn i ett program är deklarerade i olika deklarationsvidder (scope). En deklarationsvidd är ett textuellt område i programmet där namnet är känt av kompilatorn och bundet till det det är namn på (en variabel, en funktion, en typ). Obs att deklarationsvidder är en statisk, textuell gruppering av namn som bara har betydelse i källkoden och inte överlever kompilering. I C++ finns följande typer av deklarationsvidder: den globala vidden namnrymder klasser funktioner block Bild 136 8

9 Deklarationsviddsoperatorn :: Om man från utanför en deklarationsvidd vill referera till ett namn deklarerat inom en deklarationsvidd använder man viddens namn följt av deklarationsviddsoperatorn :: och det namn man vill använda (gäller inte funktioner och block, namn deklarerade i dessa vidder existerar inte utanför vidderna): std::cout << Hej hopp! << std::endl; Obs att viddens namn och :: skrivs närmast namnet, även om de ingår i ett mer sammansatt uttryck: pek->person::get_name(); Om man i en deklarationsvidd vill använda ett namn från den globala vidden som gömts av ett lokalt deklarerat namn kan man använda :: utan namn på vidden: int x=13; void funk(){ int x=173; cout << ::x; // Det globala x, 13 skrivs ut En deklarationsviddsoperator finns även i Java, men den ser ut på samma sätt som medlemsåtkomstoperatorn (alltså en punkt). Bild 137 Namnrymder Namnrymder utgör ett enkelt sätt att gruppera namn på typer (t.ex. klasser), funktioner o.s.v. som hör ihop inom ett namn: #ifndef TEXT_H #define TEXT_H #include <iostream> namespace mylib{ class Text{ Text(const char *str); int length() const; // o.s.v. ; // end of class Text std::ostream& operator<<(std::ostream&, const Text&); // end of namespace mylib #endif På det sättet uppnår man en naturlig gruppering av namn som hör ihop och undviker olösbara namnkonflikter i tillämpningar som kanske använder andra bibliotek som också deklarerar namnet Text (med en annan betydelse) Namnrymder motsvaras närmast av package i Java, men har i C++ ingen betydelse för medlemmarnas åtkomstskydd. Det finns inte heller några krav på header-/källkodsfiler, kataloger o.s.v. Bild 138 9

10 Namnrymder, forts 1. Vid definition av ett namn som deklarerats inom en namnrymd kan varje namn kvalificeras med namnrymdens namn för sig: #include Text.h #include <cstring> mylib::text::text(const char *str): size(std::strlen(str)+1), cptr(new char[size]){ std::strcpy(cptr, str); int mylib::text::length() const { return size; Men namnrymder är öppna, man kan introducera definitionerna och även deklarera nya namn i samma namnrymd: #include Text.h #include <cstring> namespace mylib{ Text::Text(const char *str): size(std::strlen(str)+1), cptr(new char[size]){ std::strcpy(cptr, str); int Text::length() const { return size; Bild 139 Namnrymder, forts. 2 Namnrymder är som sagt öppna, man kan deklarera nya namn i samma namnrymd (på samma sätt som man i Java kan deklarera flera klasser som hörande till samma package): #ifndef KLOCKA_H #define KLOCKA_H #include <iostream> namspace mylib{ class Klocka{ // o.s.v. ; std::ostream& operator<<(std::ostream&, const Klocka&); #endif Namnrymder bör användas för grova grupperingar av namn. Vid utveckling av ett bibliotek bestående av många klasser och hjälpfunktioner borde hela biblioteket göras till en namnrymd eller ett fåtal namnrymder. Bild

11 Anonyma namnrymder För att göra vissa namn privata för en modul (källkodsfil) kan man använda anonyma namnrymder: namespace{ // hjälpfunktioner, privata för modulen void helper1(.) {. void helper2(.) {. void funk() { helper1(); Inom källkodsfilen blir namnen från den anonyma namnrymden tillgängliga utan någon kvalifikation, utanför denna källkodsfil är de otillgängliga. Detta ersätter C:s deklarationer av globala namn som statiska för att gömma dem för andra moduler (mekanismen finns kvar, men bör inte användas). Bild 141 using-direktiv och using-deklarationer Med ett using-direktiv (using namespace ) som används med namnrymder öppnar man hela namnrymden, som om alla namn i namnrymden lades in i den globala namnrymden, t.ex. #include <iostream> #include <string> using namespace std; Med using-deklarationer hämtar man in ett visst namn från en annan deklarationsvidd till en lokal deklarationsvidd, t.ex. #include <iostream> #include <string> void funk(){ using std::string; using std::cout; string namn = Jozef ; cout << namn << std::endl; Bild

12 Namnrymder: namnuppslagning, alias Begrunda följande kod: #include <iostream> #include <string> //Inget using namespace std-direktiv int main(){ std::string namn( Jozef ); std::cout << namn; // Var finns operator<<(ostream&, string)? Om kompilatorn inte hittar den anropade funktionen i den lokala namnrymden letar den efter funktionen i de namnrymder där argumenttyperna är definierade (Koenig lookup). För att man inte skall dra sig för att ge namnrymder meningsfulla, långa namn kan man skapa alias till namnrymder: namespace star85_library_at_dsv_ht04{. namespace s85= star85_library_at_dsv_ht04; Bild 143 Inluppen: exempel på en liten tillämpning Vandring över skärmen med piltangenterna När markören hamnar över en knapp visas knappen med omvänd färg. Om man då trycker på RETURN utförs handlingen (värdet i displayen ökas eller minskas med 1, eller programmet avslutas). Komponenterna behöver inte vara inramade Längst ner en meny: vänster/högerpilar byter alternativ, RETURN utför handlingen. Om markören finns inom menyn fungerar tangenterna +, - och q som kortkommandon. Obs! Exemplet är mycket enkelt! Bild

13 Ett större exempel Komponenterna är inte inramade, spänner över hela fönsterbredden. Lägg märke till menyns utformning. Bild 145 Samma exempel, annan bildskärmsbild Även i Pine beror tangentkommandons betydelse på var markören befinner sig. Scrollande delfönster o.s.v. är inte så svåra att göra, men de ingår inte i den obligatoriska delen av uppgiften Bild

14 Åter till det lilla exemplet: skiss på tillämpningsprogrammet class Value{ int val; void oka() { val++; // Och visa nya värdet! void minska() { val--; // Och visa nya värdet! ; int main(){ Value v; Session ses; // Skapa displayen så att v kan visa värdet där // Skapa knappen för öka, koppla till v.oka // Skapa knappen för minska, koppla till v.minska // Skapa knappen för sluta, koppla till exit // Skapa menyn // Skapa menyvalet +, koppla till v.oka // Skapa menyvalet -, koppla till v.minska // Skapa menyvalet q, koppla till exit // Skapa kortkommandot +, koppla till v.oka // Skapa kortkommandot -, koppla till v.minska // Skapa kortkommandot q, koppla till exit ses.run(); Tillämpningen anger vid skapandet av skärmobjekten var på skärmen de skall vara, vad som skall stå i dem o.s.v. Bild 147 Inlämningsuppgiften Skapa (början till) ett klassbibliotek med komponenter för sådana tillämpningar Obligatoriska komponenter: etikett (label), knapp, editerbar sträng, meny, sammansatt komponent session Bestäm själva detaljutformningen (inramade komponenter eller ej, eller både och, färganvändning osv) Biblioteket skall vara förberett för utbyggnad, dvs utformat mer generellt än vad som krävs just här För användaren (tillämpningsprogrammeraren): bekvämt men flexibelt, dvs implementerade defaultbeteenden men möjlighet att ändra Internt: hög grad av uppdelning, varje klass sköter sina naturliga uppgifter Bild

15 Tilläggskrav på implementering Datasamlingar implementerade med STL-behållarklasser Genomgångar, sökningar osv med generiska algoritmer från standardbiblioteket Adaptorer för funktionsobjekt (bind1st, bind2nd, mem_fun osv) används där det är möjligt, egna funktionsobjekt skapas annars. Kopplingar till tillämpningsklassers metoder sker genom medlemsfunktionspekare. Komponentobjekten hanteras via referensräknande pekarklasser. Biblioteket reagerar på felaktigheter (överlappande komponenter, komponenter utanför skärmarean osv) genom att generera undantag. Icke-triviala medlemsfunktioner definieras utanför klassdefinitioner (gäller även mallar). Deklarationer av klasser i headerfiler, definitioner av medlemsfunktioner och hjälpfunktioner i implementeringsfiler (gäller inte mallar eller infogade (inline) funktioner). Hög grad av uppdelning i filer - helst varje klass på egen fil (använd make!). Bild 149 Förenklingar och önskemål Förenklingar: Icke-överlappande komponenter Önskemål: Kontroll av vilken komponent markören befinner sig i, kontroll av om komponenter överlappar varandra, eventuell beräkning av position för centrering av text osv är operationer som har att göra med rektanglar. Skapa gärna en klass rektangel med denna funktionalitet som sedan kan användas i komponentklasserna, gröta inte ner komponenterna eller sökfunktionerna med koordinataritmetik. Bild

16 En möjlig arkitektur för exemplet (instansexempel) Session getcont setcont run content add remove add Knapp öka Knapp minska Knapp sluta Menyvalen Display Meny + - q q + - main v 7 öka minska Ett tillämpningsobjekt Bild 151 Rectangle Förslag till grov klasstruktur contains Passive handle_event Component show erase enter leave handle_event Edit_string Button Compund show show show handle_event handle_event handle_event add get_text add remove Menu show handle_event add add Label show set_text Session getcontent setcontent run Action_base perform Action<> Ptr<> * -> perform Bild

17 Grov beskrivning av klasser Rectangle innehåller skärmkoordinater för en rektangulär area och medlemsfunktioner för koordinataritmetik, t.ex. contains() som tar en punkt (kolumnoch radnummer) och returnerar om denna punkt ligger inom dess area. Är mest till för hålla koordinataritmetik separerad från den övriga koden för komponenterna. Component den egentliga rotklassen i hierarkin. Borde innehålla en rent virtuell medlemsfunktion show() som implementeras i subklasserna och ritar upp komponenten på skärmen; en rent virtuell medlemsfunktion handle_event() som tar en Event-struct (så att komponenten kan se vad det var för tangent och var den trycktes) och returnerar ett booleskt värde (true om komponenten hanterat händelsen, false annars); två virtuella funktioner enter() och leave() som borde vara implementerade som tomma funktioner men kan överskuggas av subklasser om man vill att något speciellt skall hända när markören flyttas in i komponentens område resp. flyttas ut därifrån. Innehåller även icke-virtuell funktion erase() Passive rotklassen för passiva komponenter, kan implementera handle_event()- medlemsfunktionen så att den alltid returnerar false - passiva objekt reagerar inte på några händelser Bild 153 Label Grov beskrivning av klasser, forts. lövklass, implementerar show() som skriver ut texten på skärmen Edit_string lövklass, editerbar sträng som implementerar handle_event(): den reagerar på skrivbara tecken genom att lägga in dem i en intern sträng och skriva ut den förändrade strängen på skärmen samt även på delete-tangenten och rubout-tangenten genom att ta bort tecken ur strängen. Den implementerar även show() och har en egen medlemsfunktion get_text(). Denna klass borde implementeras sist. Button lövklass, implementerar show() och handle_event(): den reagerar på RETURNtangenten genom att anropa någon medlemsfunktion i något objekt av någon klass i tillämpningen. Måste alltså ha en koppling till tillämpningen (en Action_base *, se nedan Action och Action_base). Bild

18 Grov beskrivning av klasser, forts. Compound klassen för sammansatta skärmobjekt. Borde innehålla en datasamling för de ingående skärombjekten (lämpligen en vector med pekare till skärmobjekt) och en datasamling med kortkommandon (lämpligen en map med tangentkoder som nycklar och Action_base-pekare som värden - se Action och Action_base). Borde ha två funktioner add(): en för att addera komponenter och en för att addera kortkommandon, samt funktionen remove() för borttagning av komponenter. Implementerar handle_event() genom att gå leta upp den komponent inom vars area händelsen inträffat och anropa dess handle_event(). Om komponenten svarar att den inte hanterar denna händelse (eller om händelsen inträffat utanför någon ingående komponent) så kontrolleras om detta objekt självt kan hantera händelsen (t.ex. genom att titta i kortkommando -samlingen). Medlemsfunktionen show() implementeras genom att gå igenom de ingående komponenterna och anropa deras show(). Bild 155 Grov beskrivning av klasser, forts. Menu egentligen ett sammansatt objekt vars ingående komponenter endast kan vara knappar. Dessutom borde piltangenter flytta markören till nästa/föregående knapp och knapparna borde ligga bredvid varandra. Många tyckte att Meny borde vara en subklass till Compound, men det borde den inte alls. Ett subklassobjekt skall kunna användas i alla de sammanhang där ett basklassobjekt förväntas - till ett Compound-objekt kan man addera godtyckliga komponenter, men det kan man inte till ett Menu-objekt. Däremot borde Menu implementeras genom att innehålla ett Compound-objekt och de flesta medlemsfunktioner i Menu blir nog bara till anrop av motsvarande funktion i det inneslutna Compound-objektet. En bra sak vore om add-funktionen för knappar i Menu inte tog en färdigskapad knapp utan bara info om vad som skall stå på knappen och vad den skall kopplas till, då kan Menu-objektet räkna ut vilka koordinater nästa knapp i menyn skall ha och skapa knapp-objektet självt, innan det skickas vidare till add() i det inneslutna Compund-objektet. Några design-beslut om hur menyerna skall se ut (stående, liggande, knappstorleken, hur kan tillämpningen styra detta) måste göras i så fall. Bild

19 Grov beskrivning av klasser, forts. Action representerar en koppling mellan biblioteksklasser och tillämpningen. Action_base Innehåller en pekare till ett objekt av en tillämpningsklass, en medlemspekare till en medlemsfunktion i denna klass samt medlemsfunktionen perform() som anropar denna medlemsfunktion hos detta objekt. Eftersom tillämpningsklassen är okänd måste Action vara en mall. Eftersom man vill kunna ha objekt av olika instansieringar av denna mall i samma datasamling (samlingen av kortkommandon i ett Compound-objekt) så bör man skapa en basklass (som inte är en mall) till Action, nämligen Action_base. Denna basklass borde innehålla en virtual-deklaration av medlemsfunktionen perform(). I de övriga biblioteksklasser där man vill ha en koppling till tillämpningars objekt och medlemsfunktioner kan man nu ha en pekare till Action_base, som alltså kan peka ut objekt av olika instansieringar av Action. Den föreslagna klassen Action representerar en förbindelse med en medlemsfunktion i ett objekt. Man kan tänka sig att en tilläpmning även skulle vilja kunna skapa en koppling mellan bibliotekskomponenter och fristående funktioner i tillämpningen. Vill man förbereda för det kan man göra en specialisering av Action-mallen där typen man specialiserar för är en funktionspekartyp och där Action-klassen innehåller en funktionspekare istället för en objektpekare och en medlemsfunktionspekare. Bild 157 Grov beskrivning av klasser, forts. Session representerar hela terminalskärmen. Innehåller ett sammansatt objekt som i sin tur innehåller skärmobjekten. Har medlemsfunktionerna getcontent() för att returnera en pekare till det sammansatta objektet och setcontent() för att byta ut det mot ett annat. Tillämpningen skapar ett Session-objekt, adderar komponenter och kortkommandon till dess Content och anropar sedan funktionen run(). run() innehåller en loop där man läser in nästa händelse och skickar denna händelse till rätt komponent. Förutom händelseinläsning är gången precis som för ett sammansatt objekts händelsehantering. Bild

20 Generiska enheter - mallar (templates) Upprepning En mall i C++ är ett källkodsmönster för en klass- eller funktionsdefinition, där någon eller några specifika typer (eller värden) har ersatts med formella parametrar. Vid användning av mallen anges vika aktuella typer som skall användas, varvid kompilatorn genererar motsvarande klass- eller funktionsdefinition och kompilerar den (instansiering). Denna mekanism kan (speciellt i C++) liknas med en preprocessor som gör en textuell ersättning av de formella parametrarna med aktuella argument. Kompilatorn förstår dock mallar och kan i viss mån kontrollera deras syntax. Mekanismen kan även ses som en ökning av abstraktionsnivån: klasser utgör abstraktioner över objekt, men klassmallar utgör abstraktioner över klasser. Andra viktiga språk som understödjer generiska enheter är t.ex. Ada och Eiffel. Det finns även varianter av Java med generiska enheter, t.ex. GJ (Generic Java) Genom mallar stödjer C++ generisk programmering som är en annan programmeringsparadigm än objektorienterad programmering och erbjuder i många fall alternativa sätt för lösning av samma typer av problem. Bild 159 Abstraktionsnivåer Mallar Klasser (eller funktioner), alltså typer Objekt (eller anrop) Bild

21 void swap(typ& x, TYP& y){ TYP slask=x; x=y; y=slask; Funktionsmallar - exempel Mest upprepning Ur denna funktionsmall kan kompilatorn framställa funktionsdefinitioner för byte mellan variabler av godtycklig (men samma) typ för vilken tilldelning är tillåten. Genereringen av en funktions- eller klassdefinition ur en mall för ett visst mallargument kallas instansiering av mallen. Den genererade definitionen kallas en specialisering. Instansieringen för funktioner är implicit - man behöver (oftast) inte ange de aktuella mallargumenten. När kompilatorn ser anropet av en funktion med detta namn gissar den mallargumenten från argumenttypen i anropet: int main(){ int i1=13, i2=127, i3=173, i4=14; double d1=3.5, d2=7.3; swap(i1, i2); // swap(int&, int&) genereras swap(d1, d2); // swap(double&, double&) genereras swap(i3, i4); // inget genereras, swap(int&, int&) finns redan, anropas swap(i1, d1); // Fel, det finns ingen mall för swap med olika // argumenttyper Bild 161 Klassmallar - exempel: mall för en vektorklass #ifndef VECTOR_H #define VECTOR_H class Vector{ int siz, cap; TYP *arr; Vector():siz(0), cap(10), arr(new TYP[cap]){ Vector(const Vector& other); // Andra konstruktorer, destruktorn, tilldelning TYP& operator[](int pos){ return arr[pos]; const TYP operator[](int pos) const { return arr[pos]; void push_back(const TYP& val); void pop_back(){ siz--; int size() const { return siz; TYP max() const; // Andra vektoroperationer ; Som för vanliga klasser kan medlemsfunktioner definieras utanför klassdefinitionen, men Bild

22 Vector<TYP>::Vector(const Vector& other): siz(other.siz), cap(other.cap), arr(new TYP[cap]){ for(int i=0; i<siz; i++) arr[i] = other.arr[i]; template <class T> void Vector<T>::push_back(const T& val){ if (siz==cap){ T *tmp=new T[cap*=2]; for(int i=0; i<siz; i++) tmp[i]=arr[i]; delete [] arr; arr=tmp; arr[siz++]=val; TYP Vector<TYP>::max() const { if (siz == 0) throw std::length_error( Fel ); TYP m = arr[0]; for(int i=1; i<siz; i++) if (arr[i] > m) m = arr[i]; return m; #endif Mallar för definitioner av medlemsfunktioner eftersom de är medlemmar i en mall så blir deras definitioner också mallar! Dessutom måste även definitionerna finnas med i headerfilen - mer om detta senare. Obs att mallparameterns namn har bara betydelse lokalt i varje mall Bild 163 Användning av vektormallen i en tillämpning #include Vector.h // Säg att Vector-mallen finns här #include string using namespace std; class Person{ ; int main(){ Vector<int> ivec; Vector<string> svec; ivec.push_back(13); svec.push_back( Stefan ); String sm = svec.max(); int im = ivec.max(); Vector<Person> pvec; pvec.push_back(person( Jozef, 53)); pvec.push_back(person( Stefan, 61)); Instansiering av klassmallar är explicit - mallargumenten måste anges. Medlemsfunktioner instansieras först vid kompilering av ett program som anropar dem! Person pm = pvec.max(); // Fel, instansiering av // Vector<Person>::max // misslyckas, det finns ingen operator> // för Person! Bild

23 Obegränsad genericitet I många mallar måste man anta att vissa operationer kommer att vara definierade för de typer mallen kan instansieras för. Det finns inget sätt i C++ att ange sådana restriktioner för de typer mallen skall kunna instansieras för. Instansieras mallen i tillämpningen med en typ som saknar någon operation mallen förutsätter så blir det kompileringsfel vid instansiering av den (ev. medlems-) funktion som använder operationen, med felmeddelanden gällande den felaktiga koden i mallen, inte i tillämpningen. Å andra sidan kan man använda sådana mallar med fel typer så länge man inte använder de medlemsfunktioner som förutsätter den saknade operationen. Vi skall senare se hur man kan parametrisera mallar även med operationer. I andra språk som använder genericitet brukar man kunna ange vilka operationer som måste vara definierade för typer mallen instansieras för. I dessa språk får man alltså felmeddelanden vid instansiering av mallar med fel typer. Bild 165 Mer om klassmallar Obs! att i och med att klassdefinitionen är en mall så blir definitioner av dess medlemsfunktioner också mallar. Det finns nu ingenting som heter Vector, överallt där man vill använda mallen måste denna instansieras, antingen med en specifik typ, t.ex. Vector<int> eller med mallargumentet till den enhet som använder Vector<TYP>, alltså måste denna enhet också vara en mall: void printvector(const Vector<TYP>& vec){ for(int i=0; i<vec.size; i++) cout << vec[i] << endl; // Förutsätter att << är definierad // för TYP Obs att mallighet är smittsam : en funktion som skall kunna ta som ett argument en godtycklig specialisering av en mall måste själv vara en mall, om funktionen är en medlemsfunktion i en klass så måste klassen vara en mall (inte riktigt sant, se senare om medlemsfunktionsmallar), en klass som skall ha som medlem en godtycklig specialisering av en klassmall måste själv vara en mall o.s.v. Bild

24 Mer om mall- och typnamn Inuti en klassmall kan dock namnet utan mallargumenten, t.ex. Vector, användas som en förkortning för en instansiering med samma argument, t.ex. Vector<TYP> Exempelvis är definitionen av copy-konstruktorn egentligen Vector<TYP>::Vector<TYP>(const Vector<TYP>& other): siz(other.siz), cap(other.cap), arr(new TYP[cap]){ for(int i=0; i<siz; i++) arr[i] = other.arr[i]; Deklarationer med klassmallar kan bli ganska grötiga, man använder därför ofta typedefs för specialiseringar man använder frekvent: typedef Vector<int> Intvector; typedef Vector<string> Strvector; T.ex. är standardbibliotekets string egentligen bara en typedef: typedef basic_string<char, char_traits, alloc<char> > string; Den genererade klassen har inte längre tillgång till namnet på den typ mallen har specialiserats för. Om man vill kunna få fram denna typ kan man lägga in en typedef i mallen: class Vector{ typdedef TYP value_type; Vi kommer senare att se behovet av sådana konstruktioner Bild 167 Definitioner i headerfiler! Eftersom mallar instansieras först vid kompilering av program som använder dem måste deras definitioner finnas tillgängliga för kompilatorn vid kompilering av tillämpningsprogrammet. Detta innebär att definitioner av funktionsmallar och medlemsfunktionsmallar måste finnas i headerfiler (de följer samma regler som inline-funktioner). Det hindrar inte att man fortfarande gör (mallar för) klassdefinitioner först och placerarar (mallar för) medlemsfunktioner därefter, utanför (mallen för) klassdefinitionen. Om man vill kunna kontrollera syntaxen i sina mallar genom kompilering kan skapa en.cpp-fil som bara inkluderar headerfilen och kompilera den, man kan även temporärt döpa om headerfilen till ett namn med filtypen.cpp och kompilera. Obs dock att det bara är begränsad syntaxkontroll kompilatorn kan göra på oinstansierade mallar - den vet ju inte för vilka typer mallen kommer att instansieras. Bild

25 Icke-typ-mallparametrar Mallparametrar behöver inte vara typer, de kan vara värden - argumentvärdet vid instansiering måste då vara ett konstant uttryck. template<class TYP, int size> class Buffer{ int count; TYP arr[size]; Buffer():count(0){ ; int main(){ Buffer<char, 256> cbuf; Buffer<string, 10> sbuf; Obs att detta värde kompileras in, cbuf och sbuf är objekt av två helt olika klasser med konstanta storlekar på sina arrayer. Bild 169 Mallspecialiseringar är olika typer Mallspecialiseringar är helt olika typer som inte har något med varandra att göra. Exempel: class Klass{ TYP data; Klass(TYP d):data(d){ void visa() const { Klass<string> Klass<> Klass<int> cout << data << endl; ks How many ki roads must a man walk 42 down? ; int main(){ Klass<string> ks("how many roads must a man walk down?"); Klass<int> ki(42); ks.visa(); ki.visa(); Ovanstående går bra. Men om vi vill ha en samling av sådana objekt (med olika typer på data) för att gå igenom dem och anropa visa() för varje objekt så går det inte eftersom objekten är av olika typer. Bild

26 Basklasser till klassmallar Om man vill att objekt av klasser som genereras ur en mall skall kunna hanteras som hörande till samma typ (t.ex. pekas ut från samma datastruktur) måste de utrustas med en gemensam basklass (som inte är en mall): class Klass_base{ virtual void visa() const = 0; ; class Klass:public Klass_base{ TYP data; Klass(TYP d):data(d){ void visa() const { cout << data << endl; ; int main(){ Klass_base *arr[2]; arr[0]=new Klass<string>("How many roads was it?"); arr[1]=new Klass<int>(42); for(int i=0; i<2; i++) arr[i]->visa(); Den gemensamma typen är Klass_base. Obs att de funktioner som skall kunna anropas utan vetskap om typen måste virtual-deklareras i basklassen. Obs att Klass_base inte kan innehålla något som är beroende av mallargumentet (typen). Obs att objekten ny är polymorfa och bör hanteras via pekare (motsv.) Bild 171 Exempel ur inluppen I inluppen kommer man att vilja representera kopplingar till tillämpningens okända objekt av okänd typ och till en okänd medlemsfunktion i ett objektet. Detta görs med en pekare till objektet och en medlemspekare till medlemsfunktionen, men eftersom objektets typ är okänt måste det göras i en mall. Men sedan vill man kunna ha samlingar av sådana kopplingar - lösningen: en basklass: class Action_base{ virtual void perform() = 0; ; class Action : public Action_base { TYP *obj; void (TYP::*funk)(); Action(TYP *o, void(typ::*f)()):obj(o), funk(f){ void perform(){ (obj->*funk)(); ; Bild

27 Exempel ur inluppen, forts. Där man vill ha ett godtyckligt Action-objekt kan man nu ha en Action_base *: class Button : public Component{ string caption; Action_base *action; Button(, string cap, Action_base *a):, caption(cap), action(a){ bool handle_event(event eve) const { if (eve.what == terminal::return) { action->perform(); return true; else return false; Tillämpningen kan då skapa sina knappar med en koppling till en medlemsfunktion i sina objekt enligt följande exempel: new Button(, new Action<Value>(&v, &Value::oka)); (något förändrat vid användning av referensräknande smarta pekare ) Bild 173 Hjälpfunktioner för implicit instansiering av klassmallar Instansiering av funktionsmallar är implicit - kompilatorn gissar sig till mallargumenten ur funktionsanropet ( argument deduktion ). Instansiering av klassmallar är explicit - mallargumentet måste anges efter klassnamnet: new Button(, new Action<Value>(&v, &Value::oka)); För att underlätta skapande av objekt av mallklasser brukar biblioteksskapare tillhandahålla funktionsmallar för skapande av objekten - dessa funktionsmallar blir då bekvämare att använda: Action<TYP> *mk_action(typ *obj, void (TYP::*funk)()){ return new Action<TYP>(obj, funk); Tillämpningen kan nu skapa sina Action<>-objekt lite bekvämare: new Button(, mk_action(&v, &Value::oka)); Bild

28 Ett exempel från standardbiblioteket: pair<> Mallen för en struct som omsluter två värden (något förenklad). Tillgänglig genom #include <utility>, ligger i namespace std template <class T1, class T2> struct pair { typedef T1 first_type; typedef T1 second_type; T1 first; T2 second; pair() : first(t1()), second(t2()) { pair(const T1& a, const T2& b):first(a),second(b){ ; template <class T1, class T2> inline bool operator==(const pair<t1,t2>& x, const pair<t1,t2>& y){ template <class T1, class T2> inline bool operator<(const pair<t1, T2>& x, const pair<t1, T2>& y){ return x.first < y.first (!(y.first<x.first)&& x.second < y.second); o.s.v. Hjälpfunktion för implicit instansiering : template <class T1, class T2> inline pair<t1,t2> make_pair(const T1& x,const T2& y){ return pair<t1,t2>(x, y); Obs hur medlemmarna ges default-värden! Bild 175 Ett exempel från standardbiblioteket: pair<>, forts. pair<> skulle t.ex. kunna användas i inluppen om man ville ha en typ för skärmkoordinater (d.v.s. x- och y-koordinaten förpackade i en liten struct): #include <utility> namespace inlupp{ typedef pair<int, int> Koord; struct Rectangle{ bool in_my_area(const Koord& point) const throw() { return.. ; ; class.{ void funk(const Rectangle& rect) { Event eve=term.getnextevent(); if (rect.in_my_area(make_pair(eve.wherex, eve.wherey))) eller if (rect.in_my_area(koord(eve.wherex, eve.wherey))) Bild

29 Argumentdeduktion för funktionsmallar Vid implicit instansiering av funktionsmallar försöker kompilatorn deducera mallargumenten (typerna) ur typer för aktuella argumentvärden i funktionsanropet. Funktionens argument behöver inte vara av de typer som utgör mallargument, det räcker att mallargumenten framgår av funktionens argument. Exempel: template<class TYP> void funk(typ *pek){ TYP temp = *pek; ; int *ipek; funk(ipek); Funktionsargumentet är en int * så mallargumentet är int template<class TYP, int siz> void funk(typ (&arr)[siz]){ for(int i; i<siz; i++) cout << arr[i] << endl; ; char buff[128]; funk(buff); Funktionsargumentet är en char[128] så mallargumentet TYP är char och mallargumentet siz är 128 Bild 177 Explicit instansiering av funktionsmallar Ibland framgår inte mallargumenten ur funktionsargument. Detta inträffar främst då mallargumentet (typen) används som returtypen för funktionen, men inte som funktionsargumenttyp (returtypen deltar inte i deduktionen eftersom det inte alltid framgår av anropet vad den skall vara). I så fall måste mallargument anges explicit vid anropet: template <class RET, class ARG> RET funk(const ARG& param) { RET x; return x; string str; str=funk<string, int>(13); De mallargument som kan deduceras behöver inte anges om de står sist i listan: str=funk<string>(13); Bild

30 (Nästan) Ingen konvertering vid argumentdeduktion När en funktionsmall skall instansieras kollar kompilatorn om det redan finns en instans av funktionen med samma argumenttyper. Vid denna kontroll används dock inte de vanliga typkonverteringsmekanismerna. template<class TYP> TYP add(typ x, TYP y){ return x + y; Triviala konverteringar som array till pekare, funktion till funktionspekare, TYP till const TYP används dock. int i1, i2, i3; short sh1, sh2, sh3; long lo1, lo2, lo3; i3 = add(i1, i2); sh3 = add(sh1, sh2); lo3 = add(lo1, lo2); i1 = add(25, i3); // add(int, int) genereras // add(short, short) genereras // add(long, long) genereras // finns redan, används Bild 179 Överlagrade funktionsmallar Funktionsmallar kan överlagras med andra funktionsmallar och med vanliga funktioner. Det är den mest specialiserade funktionen kommer att anropas (efter eventuell instansiering). void funk(typ x){ cout << funk<typ> << endl; Vi återkommer till specialiserade mallar senare void funk(typ *x){ cout << funk<typ *> << endl; void funk(int x){ cout << funk<int> << endl; int main(){ int i=15; int *ipek=&i; string str( Jozef ); funk(i); // Skriver funk<int> funk(ipek); // Skriver funk<typ *> funk( Jozef ); // Skriver funk<typ *> funk(str); // Skriver funk<typ> Bild

31 Exempel från inluppen Man kan tänka sig att Action<>-objekt även borde kunna knytas till fria funktioner och till medlemsfunktioner som kan ta t.ex. en knapps textsträng som argument. Man kan inte ha flera klasser med samma namn, så klassmallar kan inte överlagras, vi får hitta på nya namn för sådana klasser: class Action_arg : public Action_base { std::string arg; TYP *obj; void (TYP::*funk)(std::string); Action_arg(std::string a, TYP *o, void(typ::*f)(std::string)): arg(a), obj(o), funk(f){ void perform(){ (obj->*funk)(arg); ; class Action_free : public Action_base { // Inte ens en mall void (*funk)(); Action_free(void(*f)()):funk(f){ void perform(){ funk(); ; Bild 181 Exempel från inluppen, forts. Vi kan dock underlätta för tillämpningsprogrammerare genom att skapa överlagrade funktionsmallar för hjälpfunktioner: template <class T> Action_arg<T> *mk_action(string a, T *o, void (T::*f)(string)){ return new Action_arg<T>(a, o, f); Action_free *mk_action(void (*funk)()){ return new Action_free(funk); Tillämpningsprogrammeraren kan nu skapa sina Action<>-objekt på samma sätt : new Button(, mk_action(&v, &Value::oka)); new Button(, mk_action( Minska, &v, &Value::minska)); new Button(, mk_action(quit)); Bild

32 Statiska medlemmar i klassmallar Varje mallspecialisering får sin egen kopia av statiska medlemmar: class Counted{ static int count; TYP data; Counted(TYP s):data(s){ count++; Counted(const Counted& other):data(other.data){ count++; ~Counted(){ count--; TYP get_data() const { return data; static int get_count(); ; int Counted<TYP>::count=0; int Counted<TYP>::get_count(){ return count; Klasser genererade ur denna mall (t.ex. Counted<int>, Counted<string>) har inget gemensamt, varje klass kommer att ha en egen count och get_count(). Bild 183 Statiska medlemmar över mallgränser Vill man att klasser genererade ur en mall skall ha en gemensam typ och/eller medlemmar måste de ha en gemensam basklass: class Counted{ static int totcount; Counted(){ totcount++; Counted(const Counted& other)( totcount++; virtual ~Counted(){ totcount--; static int get_totcount(); ; int Counted::totcount=0; int Counted::get_totcount() { return totcount; // fortsättning på nästa bild Bild

33 Statiska medlemmar över mallgränser - forts. class DataCounted : public Counted{ static int count; TYP data; DataCounted(TYP d):data(d){count++;//default-ktor anropas DataCounted(const DataCounted<TYP>& other): Counted(other), data(other.data){count++; ~DataCounted(){count--; // Counted-dtor anropas automatiskt TYP get_data() const { return data; static int get_count(); ; int DataCounted<TYP>::count=0; int DataCounted<TYP>::get_count(){ return count; Bild 185 Statiska medlemmar över mallgränser - användning. int main(){ DataCounted<int> di1(13), di2(77); DataCounted<string> ds1( Peter ), ds2( Ulla ); cout << Totalt << Counted::get_totcount(); cout << varav int << DataCounted<int>::get_count(); cout << och str << DataCounted<string>::get_count(); Bild

34 friend-deklarationer i klassmallar Med en friend-deklaration i en klassmall kan man mena tre olika saker: 1. vännen är en viss specifik funktion eller klass 2. vännen är en instans av en funktions- eller klassmall instansierad med samma typ (-er) som denna klass I detta fall måste deklarationer av dessa funktions- eller klassmallar finnas inom deklarationsvidden, före klassmallen som deklarerar dem som vänner Speciell syntax (se nästa bild). 3. vännen är en godtycklig instans av en viss funktions- eller klassmall. I detta fall blir friend-deklarationen i klassen en mall i sig: class Klass{ template <class TYP2> friend void funk(const TYP2&); Bild 187 friend-deklarationer i klassmallar, exempel Exempel på fall 2 från föregående bild: säg att vi vill lösa problemet med den specialiserade swap-funktionens åtkomst till Vectors privata data genom att deklarera swap-funktionen som vän: void swap(typ& x, TYP& y); class Vector; void swap(vector<typ>& x, Vector<TYP>& y); class Vector{ friend void swap<typ>(vector<typ>&, Vector<TYP>&); ; void swap(vector<typ>& x, Vector<TYP>& y){ int s=x.siz, c=x.cap; TYP *a = x.arr; x.siz=y.siz; x.cap=y.cap; x.arr=y.arr; y.siz=s; y.cap=c; y.arr=a; Bild

35 Medlemsmallar I standard-c++ kan man göra medlemmar i en klass (eller klassmall) till mall. Syntaktiskt exempel: class Klass{ string namn; Klass(string n):namn(n){ ; void skriv(const TYP& meddel) const { cout << namn << : << meddel; int main(){ Klass teacher( Jozef ); const string tidsenh( minuter ); teacher.skriv( Vi tar paus på ); teacher.skriv(17); teacher.skriv(tidsenh); Bild 189 Medlemsmallar, mer realistiskt exempel Säg att vi i vår Vector<>-mall vill ha en konstruktor som initierar vektorn med värden som tas från vilken annan typ av behållare som helst, bara elementen är av rätt typ och kan pekas ut av pekare (eller något som beter sig som pekare): class Vector{ int siz, cap; TYP *arr; template <class PEKTYP> // Deklaration Vector(PEKTYP pek1, PEKTYP pek2); ; // Definition template <class PEKTYP> Vector<TYP>::Vector(PEKTYP pek1, PEKTYP pek2): siz(0), cap(10), arr(new TYP[cap]) { while (pek1!= pek2) push_back(*pek1++); Bild

36 Medlemsmallar, forts. Exempel på användning: #include <list> #include Vector.h int main(){ list<int> li; int arr[] = {13, 7, 78, 53, 92; const int arrsize = sizeof(arr) / sizeof(int); for(int i=0; i<arrsize; i++) li.push_back(arr[i]); Vector<int> v1(li.begin(), li.end()); // Vector<int>::Vector(list<int>::iterator,list<int>::iterator) Vector<int> v2(&arr[0], &arr[arrsize]); // Vector<int>::Vector(int *, int *) Bild 191 Konvertering mellan mallspecialiseringar I vissa speciella situationer vill man att objekt av olika klasser genererade ur samma mall skall kunna konverteras till varandra. Detta inträffar t.ex. för mallar för referensräknande pekarklasser som skall användas för att peka ut objekt ur en klasshierarki: ett pekarobjekt för basklassen skall kunna tilldelas från ett pekarobjekt för subklassen enligt de vanliga reglerna för basklass-/subklass-pekare. För att möjliggöra detta får man i mallen för pekarklassen skapa en mall för konverteringsoperatorer. Först en repetition av konverteringsoperatorer: class Alfa{ ; class Beta{ operator Alfa() { // Detta är en konverteringsoperator som anger // hur man gör ett Alfa-objekt ur Beta-objektet ; Bild

37 Konvertering mellan mallspecialiseringar, forts. Om det istället är fråga om konverteringar mellan två klasser genererade ur samma mall för man göra en mall för konvertering till specialisering för en annan typ: class Alfa{ template <class ANNANTYP> operator Alfa<ANNANTYP>(); ; template <class ANNANTYP> Alfa<TYP>::operator Alfa<ANNANTYP>(){ return ett temporärt Alfa<ANNANTYP>-objekt konstruerat ur detta Alfa<TYP>-objekt Bild 193 Mall för pekarklass för polymorfa objekt class null_pointer; // Undantagsklass, visas senare template <class T> class Ptr{ T *ptr; int *count; template<class U> friend class Ptr; Ptr(T *p, int *c); // Privat konstruktor, används vid konvertering Ptr(T *p=0) throw(std::bad_alloc); Ptr(const Ptr& other) throw(); ~Ptr() throw(); const Ptr& operator=(const Ptr& other) throw(); T& operator*() throw(null_pointer); const T& operator*() const throw(null_pointer); T* operator->() throw(null_pointer); const T* operator->() const throw(null_pointer); bool operator==(const Ptr& other) const throw(); bool operator!=(const Ptr& other) const throw(); operator T*() const throw(); // Konvertering till vanlig pekare template <class OTHERTYPE> // Konvertering till Ptr för annan operator Ptr<OTHERTYPE>(); // typ (basklasstyp) ; Bild

Föreläsning 11 Genomgång av inlämningsuppgiften

Föreläsning 11 Genomgång av inlämningsuppgiften *:85/ID200V C++ HT07 Föreläsning 11 Genomgång av inlämningsuppgiften Inluppen: exempel på en liten tillämpning Vandring över skärmen med piltangenterna När markören hamnar över en knapp visas knappen med

Läs mer

*:85/ID200V C++ HT07. Föreläsning 8 Medlemspekare Undantagshantering Namnrymder

*:85/ID200V C++ HT07. Föreläsning 8 Medlemspekare Undantagshantering Namnrymder *:85/ID200V C++ HT07 Föreläsning 8 Medlemspekare Undantagshantering Namnrymder Medlemspekare Ibland uppstår behovet att peka ut en viss medlem, som skall behandlas i olika objekt. C++ har begreppet medlemspekare

Läs mer

Föreläsning Mallar

Föreläsning Mallar *:85/ID200V C++ HT07 Föreläsning 12-14 Mallar Generiska enheter - mallar (templates) Upprepning En mall i C++ är ett källkodsmönster för en klass- eller funktionsdefinition, där någon eller några specifika

Läs mer

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

Programmering i C++ EDA623 Objektorienterad programutveckling. EDA623 (Föreläsning 5) HT 2013 1 / 33 Programmering i C++ EDA623 Objektorienterad programutveckling EDA623 (Föreläsning 5) HT 2013 1 / 33 Objektorienterad programutveckling Innehåll Grundläggande begrepp Relationer mellan objekt Grafisk representation

Läs mer

Kapitel 6 - Undantag

Kapitel 6 - Undantag Kapitel 6 Undantag Kapitel 6 - Undantag Undantag (exceptions), returvärden throw, try och catch new, bad_alloc, nothrow Undantag och std::auto_ptr throw() i funktionsdeklaration try som funktionskropp

Läs mer

TDIU01 Programmering i C++

TDIU01 Programmering i C++ TDIU01 Programmering i C++ Föreläsning 6 - Klasser Eric Elfving, eric.elfving@liu.se Institutionen för datavetenskap (IDA) Avdelningen för Programvara och system (SaS) Klasser När vi skapade vår lista

Läs mer

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

TDIU20 - Objektorienterad programmering i c++ - föreläsning 4 TDIU20 - Objektorienterad programmering i c++ - föreläsning 4 Pontus Haglund Department of Computer and information science 1 Vad gjorde vi förra gången? Felhantering Operatorer Typkonvertering 2 Grundläggande

Läs mer

Det finns många flaggor till g++,

Det finns många flaggor till g++, C++, Övning 1 Jonas Sjöbergh, jsh@nada.kth.se Inge Frick, inge@nada.kth.se Alexander Baltsatsis hur man kompilerar och kör make preprocessor minnesallokering, pekare grundläggande C++, funktioner m.m.

Läs mer

Introduktion till arv

Introduktion till arv Introduktion till arv 6 INTRODUKTION TILL ARV Arv Generell-Speciell Arv för att utnyttja det vi redan gjort Återanvändning Basklass Härledd klass Varför arv? Inför en subklass för att uttrycka specialisering

Läs mer

Föreläsning 4 Tillägg till C-syntaxen

Föreläsning 4 Tillägg till C-syntaxen *:85/ID200V C++ HT07 Föreläsning 4 Tillägg till C-syntaxen Några småsaker Resten-av-raden -kommentarer // (som i Java) Datatypen bool med värdena false och true, implicit kompatibel med int (d.v.s. int-värden

Läs mer

Tentamen *:85/2I4123 C

Tentamen *:85/2I4123 C DSV Sid 1(6) *:85/2I4123 Jozef Swiatycki 2006-01-21 Tentamen *:85/2I4123 C++ 2006-01-21 Denna tentamen består av fyra uppgifter som tillsammans kan ge maximalt 30 poäng. För godkänt resultat krävs minst

Läs mer

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

Kapitel 3. Synlighet. Kapitel 3 - Klassanvändning, operatorer och pekare. Synlighet Kapitel 3 Klassanvändning Operatorer Pekare Kapitel 3 - Klassanvändning, operatorer och pekare Vänner till klasser och funktioner Virtuella funktioner och polymorfi Abstrakta basklasser och strikt virtuella

Läs mer

Innehåll. Pekare Exempel

Innehåll. Pekare Exempel Innehåll EDAF30 Programmering i C++ Avslutning. Sammanfattning och frågor 1 Syntax, förklaringar Sven Gestegård Robertz Datavetenskap, LTH 2017 2 Stack-allokering Heap-allokering: new och delete 3 Avslutning.

Läs mer

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

Programmering i C++ EDA623 Arv. EDA623 (Föreläsning 6) HT 2013 1 / 42 Programmering i C++ EDA623 Arv EDA623 (Föreläsning 6) HT 2013 1 / 42 Arv Innehåll Härledda klasser Konstruktorer och destruktorer vid arv Tillgänglighet Polymorfism och dynamisk bindning Abstrakta klasser

Läs mer

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

Innehåll. Exceptionella händelser (exceptions, undantag ) Felhantering Tre nivåer av felhantering: Nivå 2: exceptions (eller returvärde) Innehåll EDAF30 Programmering i C++ 7. Felhantering. Sven Gestegård Robertz Datavetenskap, LTH 2017 1 Felhantering Exceptions Exceptions och resurshantering Specifikation av exceptionella händelser Static

Läs mer

Innehåll. Pekare Exempel

Innehåll. Pekare Exempel Innehåll EDAF30 Programmering i C++ Avslutning. Sammanfattning och frågor 1 Syntax, förklaringar Sven Gestegård Robertz Datavetenskap, LTH 2016 2 Stack-allokering Heap-allokering: new och delete 3 Avslutning.

Läs mer

TDIU01 - Programmering i C++, grundkurs

TDIU01 - Programmering i C++, grundkurs TDIU01 - Programmering i C++, grundkurs Sammanfattning period 1 Eric Elfving Institutionen för datavetenskap 1 oktober 2013 Översikt Ett C++-programs uppbyggnad Variabler Datatyper Satser Uttryck Funktioner

Läs mer

TDIU01 - Programmering i C++, grundkurs

TDIU01 - Programmering i C++, grundkurs TDIU01 - Programmering i C++, grundkurs Pekare och Listor Eric Elfving Institutionen för datavetenskap 31 oktober 2014 Översikt 2/41 Internminne Pekare Dynamiska datastrukturer (Enkellänkade) listor Arbeta

Läs mer

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

Innehåll. Introduktion till objektorientering. OOP (objektorienterad programmering) Objekt, instanser, klasser Föreläsning 1 Innehåll Introduktion till objektorientering OOP (objektorienterad programmering) Objekt, instanser, klasser C++ OO i C++ Standardbibliotek Utökningar från C (syntaktiskt socker) Introduktion

Läs mer

Synlighet. Namespace Scope-operatorn Klasser Vänner

Synlighet. Namespace Scope-operatorn Klasser Vänner Synlighet Namespace Scope-operatorn Klasser Vänner Synlighet Ett problem med moduler i C är att alla variabel- och funktionsnamn ligger globalt synliga. C++ botar detta genom att införa det mycket användbara

Läs mer

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

Innehåll. Pekaren this Självreferens. Klasser Resurshantering, representation. Överlagring av operatorer. Överlagring av operatorer Innehåll EDAF30 Programmering i C++ 8. Klasser; resurshantering och polymorfism Sven Gestegård Robertz Datavetenskap, LTH 2016 1 Klasser 2 Operatorer 3 Klasser, resurshantering Rule of three Move semantics

Läs mer

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

Del3 Klassanvändning, operatorer och pekare Ämnesområden denna föreläsning: 2D1387, Programsystemkonstruktion med C++ 00/01 1 Del3 Klassanvändning, operatorer och pekare Ämnesområden denna föreläsning: Synlighet Överlagring av operatorer Slide 1 Vänner till klasser och funktioner

Läs mer

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

Innehåll. 1 Kort om dynamisk polymorfism. 2 Arv i C++ 3 Multipelt arv. 4 Något om statisk polymorfism. class Container { Innehåll EDAF30 Programmering i C++ Arv. Polymorfism. Sven Gestegård Robertz Datavetenskap, LTH 2015 1 Kort om dynamisk polymorfism Virtuella funktioner 2 Arv i C++ Konstruktorer och destruktorer Tillgänglighet

Läs mer

Programmering i C++ EDA623 Mallar. EDA623 (Föreläsning 12) HT / 29

Programmering i C++ EDA623 Mallar. EDA623 (Föreläsning 12) HT / 29 Programmering i C++ EDA623 Mallar EDA623 (Föreläsning 12) HT 2013 1 / 29 Mallar Innehåll Klassmallar Funktionsmallar EDA623 (Föreläsning 12) HT 2013 2 / 29 Containerklasserna vector, deque och list utgör

Läs mer

Föreläsning 5-7 Operatoröverlagring

Föreläsning 5-7 Operatoröverlagring *:85/ID200V C++ HT07 Föreläsning 5-7 Operatoröverlagring Operatoröverlagring Följande operatorer kan inte överlagras: ::..*?: sizeof typeid Alla övriga operatorer kan överlagras. Följande operatorer måste

Läs mer

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

Övriga byggstenar. Övriga byggstenar. Några tips under programutveckling. Beroenden Pekare till funktioner Typkonvertering Övriga byggstenar Beroenden Pekare till funktioner Övriga byggstenar Beroenden er Definitioners synlighet Funktionspekare Icke-medlemsfunktioner Medlemsfunktioner 2D1387 Programsystemkonstruktion med C++

Läs mer

SP:PROG3 HT12 Tenta 2013-01-19

SP:PROG3 HT12 Tenta 2013-01-19 DSV SU/KTH sid 1 (5) SP:PROG3 SP:PROG3 HT12 Tenta 2013-01-19 Tentan består av tre uppgifter. Max poäng är 30. För betyget E (godkänd) krävs minst 18 poäng och minst en poäng på varje uppgift. Betygskriteria

Läs mer

DAT043 - föreläsning 8

DAT043 - föreläsning 8 DAT043 - föreläsning 8 Paket, generics, Java collections framework 2017-02-07 Paket och tillgänglighet Ovanför klasser finns en hierarkisk namespace med paket. Filer som inte deklareras i något paket finns

Läs mer

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

DD2387 Programsystemkonstruktion med C++ Tentamen 1 Torsdag 7 januari 2016, 14:00-18:00 DD2387 Programsystemkonstruktion med C++ Tentamen 1 Torsdag 7 januari 2016, 14:00-18:00 Introduktion Skriv dina svar på separata papper, dessa scannas in efter inlämning. Du kan skriva på både fram- och

Läs mer

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

Innehåll. Resurshantering. Resource handles. Minnesallokering. Minnesallokering Exempel: allokering på stacken. 6. Resurshantering Innehåll EDAF30 Programmering i C++ 6. Resurshantering Sven Gestegård Robertz Datavetenskap, LTH 2017 1 Resurshantering Stack-allokering Heap-allokering: new och delete 2 Smarta pekare 3 Klasser, resurshantering

Läs mer

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

C++ Objektorientering - Klasser. Eric Elfving Institutionen för datavetenskap C++ Objektorientering - Klasser Eric Elfving Institutionen för datavetenskap 1 / 23 Återblick struct struct är bra att ha för att skapa aggregat - slå ihop flera data till en ny datatyp. Ett problem med

Läs mer

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

Innehåll. Resource handles. Resurshantering. Minnesallokering. Minnesallokering Exempel: allokering på stacken. 7. Resurshantering, Felhantering Innehåll EDAF30 Programmering i C++ 7. Resurshantering, Felhantering Sven Gestegård Robertz Datavetenskap, LTH 2016 1 Resurshantering Stack-allokering Heap-allokering: new och delete 2 Felhantering Exceptions

Läs mer

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

Operatoröverlagring. endast operatorsymboler definierade i C++ kan överlagras = += -= *= /= %= ^= &= = <<= >>= < > <= >= ==!= && > ->*, [ ] ( ) TDDC76 PoD OH Föreläsning C++ 83 Operatoröverlagring endast operatorsymboler definierade i C++ kan överlagras + - * / % ^ & ~! > = += -= *= /= %= ^= &= = = < > = ==!= && ++ -- -> ->*, [ ]

Läs mer

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

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList. Institutionen för Datavetenskap Göteborgs universitet HT2009 DIT011 Objektorienterad programvaruutveckling GU (DIT011) Föreläsning 3 Innehåll Lite om felhantering och Exceptions Mer om variabler och parametrar

Läs mer

TDDC76 - Programmering och Datastrukturer

TDDC76 - Programmering och Datastrukturer TDDC76 - Programmering och Datastrukturer Objektorientering - Klasser Eric Elfving Institutionen för datavetenskap 1 / 20 Återblick struct struct är bra att ha för att skapa aggregat - slå ihop flera data

Läs mer

Dynamisk bindning och polymorfism

Dynamisk bindning och polymorfism Dynamisk bindning och polymorfism I C++ är pekare till basklasser polymorfa, dvs de kan peka på objekt av en subklass typ Vid statisk bindning sker all bindning vid kompileringen -> Vid ett metodanrop

Läs mer

C++ Objektorientering - Klasser. Eric Elfving

C++ Objektorientering - Klasser. Eric Elfving C++ Objektorientering - Klasser Eric Elfving 1 / 20 Återblick struct struct är bra att ha för att skapa aggregat - slå ihop flera data till en ny datatyp. Ett problem med struct är åtkomst... 2 / 20 Följande

Läs mer

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

Del2 Klasser, medlemmar och arv Ämnesområden denna föreläsning: 2D1387, Programsystemkonstruktion med C++ 00/01 1 Del2 Klasser, medlemmar och arv Ämnesområden denna föreläsning: Klasser, åtkomst Medlemmar, medlemsfunktioner, inline Slide 1 Konstruktorer Destruktorer

Läs mer

Arrayer. results

Arrayer. results Arrayer 85 Arrayer Deklarerar utrymme för många variabler i en enda deklaration Array (fält) Varje värde har ett numeriskt index i Java indexeras en array med N element med indexen till N-1 Exempel: 1

Läs mer

Exempel. Arrayer. Lösningen. Ett problem. Arrayer och hakparanteser. Arrayer

Exempel. Arrayer. Lösningen. Ett problem. Arrayer och hakparanteser. Arrayer Exempel for (int antal=; antal < 75; antal++) System.out.println (antal); Arrayer for (int num=5; num

Läs mer

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

grundläggande C++, funktioner m.m. C++, Övning 1 Jonas Sjöbergh, jsh@nada.kth.se hur man kompilerar och kör make preprocessor minnesallokering, pekare grundläggande C++, funktioner m.m. ett exempel Ett enkelt program i C++, hello.cpp #include

Läs mer

TDDC76 - Programmering och Datastrukturer

TDDC76 - Programmering och Datastrukturer TDDC76 - Programmering och Datastrukturer Objektorientering - Arv och polymorfi Eric Elfving Institutionen för datavetenskap 1 / 25 Med hjälp av arv kan vi bryta ut saker som är gemensamt hos flera klasser.

Läs mer

Programsystemkonstruktion med C++

Programsystemkonstruktion med C++ Programsystemkonstruktion med C++ Övning 2 Daniel Aarno bishop@kth.se Översikt övning 2 Klasser Konstruktorer Destruktorer Arv Virtuella funktioner Abstrakta klasser Operatorer Templateklasser Templatefunktioner

Läs mer

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

Programmering i C++ EDA623 Mer om klasser. EDA623 (Föreläsning 6) HT 2013 1 / 26 Programmering i C++ EDA623 Mer om klasser EDA623 (Föreläsning 6) HT 2013 1 / 26 Mer om klasser Innehåll Konstanta objekt Statiska medlemmar Pekaren this Vänner (friends) Överlagring av operatorer EDA623

Läs mer

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

Innehåll. 1 Funktionsmalllar. 2 Klassmallar. struct Name { string s; //... }; const Name & minimum ( const Name & a, const Name & b) { if(a.s < b. Innehåll EDAF30 Programmering i C++ Generisk programmering med templates (mallar) Sven Gestegård Robertz Datavetenskap, LTH 2015 1 Funktionsmalllar 2 Generisk programmering med templates (mallar) 2/1 Generisk

Läs mer

Ett problem. Kontrollstrukturer och arrayer. Arrayer. Lösningen. Arrayer och hakparanteser. Exempel int[] results; results = new int[10]; // 0..

Ett problem. Kontrollstrukturer och arrayer. Arrayer. Lösningen. Arrayer och hakparanteser. Exempel int[] results; results = new int[10]; // 0.. Ett problem Kontrollstrukturer och er Hur sparas data T ex när man vill spara resultaten av en tävling Exempel med 3 deltagare: public class Competition private int result1; private int result2; private

Läs mer

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

Programsystemkonstruktion med C++: Övning 2. Karl Palmskog september 2010 Programsystemkonstruktion med C++: Övning 2 Karl Palmskog palmskog@kth.se september 2010 Specalfunktioner i klasser Konstruktorer i konstruktorerna för en klass initieras klassens medlemmar initialvärden

Läs mer

Funktionspekare, inledning: funktionsanropsmekanismen. Anrop via pekare

Funktionspekare, inledning: funktionsanropsmekanismen. Anrop via pekare Funktionspekare, inledning: funktionsanropsmekanismen Vid funktionsanrop läggs aktuella argumentvärden och återhoppsadressen på stacken, därefter sker ett hopp till adressen för funktionens första instruktion.

Läs mer

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

Programsystem konstruktion med C++ (2D1387) Innehåll. övning 2 klasser och arv Programsystem konstruktion med C++ (2D1387) övning 2 klasser och arv Ronnie Johansson rjo@nadakthse grupp 4 2003 09 25 Innehåll Klasskonstruktorer och initieringslistor Klassdestruktorer Åtkomstkontroll

Läs mer

Tommy Färnqvist, IDA, Linköpings universitet

Tommy Färnqvist, IDA, Linköpings universitet Föreläsning 9 Pekare, länkade noder, länkade listor TDDD86: DALP Utskriftsversion av föreläsning i Datastrukturer, algoritmer och programmeringsparadigm 25 september 2015 Tommy Färnqvist, IDA, Linköpings

Läs mer

1 Klasser och objektorientering Vad är objektorientering?

1 Klasser och objektorientering Vad är objektorientering? 1 Klasser och objektorientering Vad är objektorientering? Det finns olika synsätt på programmering, dessa olika synsätt kallas för paradigm. De vanligaste paradigmen är det imperativa/proceduriella, det

Läs mer

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

Objektorientering - Arv och polymorfi. Eric Elfving Institutionen för datavetenskap Objektorientering - Arv och polymorfi Eric Elfving Institutionen för datavetenskap 1 / 25 Med hjälp av arv kan vi bryta ut saker som är gemensamt hos flera klasser. Vi får också möjlighet att referera

Läs mer

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

Innehåll. Typomvandlingar (casting) Implicita Typomvandlingar. Typomvandlingar (type casts) Explicita, namngivna typomvandlingar (C++-11) Innehåll EDAF30 Programmering i C++ 8. Typomvandlingar. Klasser: operatorer och polymorfism. 1 Typomvandlingar Sven Gestegård Robertz Datavetenskap, LTH 2017 2 Klasser Operatorer 3 Polymorfism och arv

Läs mer

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

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering Föreläsning 1 Objektorienterad programmering DD1332 Introduktion till Java Kompilering, exekvering, variabler, styrstrukturer Kompilering och exekvering Ett program måste översättas till datorns språk

Läs mer

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

Klasser. Kapitel 2. Kapitel 2 - Klasser, medlemmar och arv. Klasser. Klasser Medlemmar Arv Kapitel 2 Klasser Medlemmar Arv, medlemmar och arv Klasser, åtkomst Medlemmar, medlemsfunktioner, inline och destruktorer this-pekaren Arv, åtkomst Multipelt arv, virtuell basklass Konstanta funktioner

Läs mer

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

LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p UMEÅ UNIVERSITET Datavetenskap 010530 LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p Betygsgränser 3 21,5-27 4 27,5-33,5 5 34-43 Uppgift 1. (4p) Hitta de fel som finns i nedanstående klass (det

Läs mer

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

Ett enkelt program i C++, hello.cpp. #include <iostream> int main() { std::cout << Hello World\n; return 0; } C++, Övning 1 Ett enkelt program i C++, hello.cpp C++, Övning 1 Jonas Sjöbergh, jsh@nada.kth.se hur man kompilerar och kör make preprocessor minnesallokering, pekare grundläggande C++, funktioner m.m. ett exempel int

Läs mer

C++-programmets beståndsdelar

C++-programmets beståndsdelar C++-programmets beståndsdelar Ett C++-program är uppdelat i headerfiler (fil.h) och implementationsfiler (fil.cpp) Programmet måste innehålla åtminstone funktionen int main() main() startar programmet

Läs mer

Tentamen i TDP004 Objektorienterad Programmering Lösningsförslag

Tentamen i TDP004 Objektorienterad Programmering Lösningsförslag Tentamen i TDP004 Objektorienterad Programmering Lösningsförslag Datum: 2008-08-14 Tid: 08-12 Plats: PC6-PC7 i E-huset. Jour: Per-Magnus Olsson, tel 285607 Jourhavande kommer att besöka skrivsalarna varje

Läs mer

5 Arv och dynamisk bindning FIGUR

5 Arv och dynamisk bindning FIGUR 5 Arv och dynamisk bindning Arv är en av hörnstenarna i objektorienterad programmering. Med hjälp av arv kan man skapa underhållsvänliga och förändringsvänliga system. Att hitta arvsrelationer är en viktig

Läs mer

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

Innehåll. 1 Typdeklarationer och typomvandling 2 Resurshantering. 3 Objektorientering, kort repetition. 4 Klasser Innehåll EDAF30 Programmering i C++ Resurshantering. Objektorientering. Klasser. Sven Gestegård Robertz Datavetenskap, LTH 2015 1 Typdeklarationer och typomvandling 2 Resurshantering Stack-allokering Heap-allokering:

Läs mer

Byggstenar. C++-programmets beståndsdelar. C++-programmets beståndsdelar. Grundläggande datatyper

Byggstenar. C++-programmets beståndsdelar. C++-programmets beståndsdelar. Grundläggande datatyper C++-programmets beståndsdelar Ett C++-program är uppdelat i headerfiler (fil.h) och implementationsfiler (fil.cpp) Programmet måste innehålla åtminstone funktionen int main() main() startar programmet

Läs mer

2D1387, Programsystemkonstruktion med C++ 01/02 1

2D1387, Programsystemkonstruktion med C++ 01/02 1 2D1387, Programsystemkonstruktion med C++ 01/02 1 Slide 1 Del4 Klassmallar, funktionsmallar och STL Ämnesområden denna föreläsning: Funktionsmallar (function templates) Klassmallar Mallar för medlemmar

Läs mer

Lektionsuppgifter. TDDI14 Objektorienterad programmering. Lektionsplanering Lektion Lektion Lektion

Lektionsuppgifter. TDDI14 Objektorienterad programmering. Lektionsplanering Lektion Lektion Lektion LINKÖPINGS TEKNISKA HÖGSKOLA Institutionen för datavetenskap Programvara och system Tommy Olsson 2014-02-05 Lektionsplanering.................................. 2 Lektion 1..........................................

Läs mer

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

Innehåll. Användardefinierade typer. Användardefinierade typer Kategorier. Konstruktorer. Konstruktorer Två sätt att skriva initiering av medlemmar Innehåll EDAF30 Programmering i C++ 3. Mer om klasser. Funktionsanrop Sven Gestegård Robertz Datavetenskap, LTH 2017 1 Klasser pekaren this const för objekt och medlemmar Kopiering friend inline 2 Funktionsanrop

Läs mer

TDIU01 - Programmering i C++, grundkurs

TDIU01 - Programmering i C++, grundkurs TDIU01 - Programmering i C++, grundkurs Underprogram - Funktioner Eric Elfving Institutionen för datavetenskap 18 september 2014 Översikt 2/22 Återblick till satsblocken Funktioner - Namngivna satsblock

Läs mer

Tentamen *:58/ID100V Programmering i C Exempel 3

Tentamen *:58/ID100V Programmering i C Exempel 3 DSV Tentamen *:58/ID100V Sid 1(5) Tentamen *:58/ID100V Programmering i C Exempel 3 Denna tentamen består av fyra uppgifter som tillsammans kan de ge maximalt 22 poäng. För godkänt resultat krävs minst

Läs mer

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

KLASSER. Inkapsling Abstrakt datatyp Public och private. Klassmedlemmar Datamedlemmar Exempel Funktionsmedlemmar KLASSER Inkapsling Abstrakt datatyp Public och private Klassmedlemmar Datamedlemmar Funktionsmedlemmar Initiering av objekt Konstruktor Ta del av objektets tillstånd Förändra objektets tillstånd Avinitiera

Läs mer

2D1387 Programsystemkonstruktion med C++ Laboration 1: Grundläggande C++ 31 augusti 2005

2D1387 Programsystemkonstruktion med C++ Laboration 1: Grundläggande C++ 31 augusti 2005 2D1387 Programsystemkonstruktion med C++ Laboration 1: Grundläggande C++ 31 augusti 2005 I den här labben kommer du att lära dig att använda grundläggande C++ såsom klasser, loopar, variabler och minneshantering.

Läs mer

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

Introduktion. Klasser. TDP004 Objektorienterad Programmering Fö 2 Objektorientering grunder Introduktion TDP004 Objektorienterad Programmering Fö 2 Objektorientering grunder OO är den mest använda programmeringsparadigmen idag, viktigt steg att lära sig och använda OO. Klasser är byggstenen i

Läs mer

Tentamen EDAF30 Programmering i C++

Tentamen EDAF30 Programmering i C++ LUNDS TEKNISKA HÖGSKOLA 1(5) Institutionen för datavetenskap Tentamen EDAF30 Programmering i C++ 2017 04 20, 14:00 19:00 Hjälpmedel: En valfri C++-bok. Andra papper med anteckningar eller utskrifter är

Läs mer

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

Idag. Javas datatyper, arrayer, referenssemantik. Arv, polymorfi, typregler, typkonvertering. Tänker inte säga nåt om det som är likadant som i C. Idag Javas datatyper, arrayer, referenssemantik Klasser Arv, polymorfi, typregler, typkonvertering Strängar Tänker inte säga nåt om det som är likadant som i C. Objectorienterad programmering Sida 1 Ett

Läs mer

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

Innehåll. Konstruktorer vid arv Regler för basklassens konstruktor. Konstruktorer vid arv. Konstruktorer vid arv. Konstruktorer vid arv Innehåll EDAF30 Programmering i C++ 9. Polymorfism och arv Sven Gestegård Robertz Datavetenskap, LTH 2017 1 Klasser Polymorfism och arv Konstruktorer och destruktorer Tillgänglighet Arv utan polymorfism

Läs mer

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

Innehåll. Parametriserade typer. Klassmallar. Klassmallen Vektor Konstructor med std::initializer_list. Klassmallen Vektor Medlemsfunktioner Innehåll EDAF30 Programmering i C++ 10. Generisk programmering. Mallar och funktionsobjekt Sven Gestegård Robertz Datavetenskap, LTH 2017 1 Funktionsobjekt Mallar med variabelt antal argument 10. Generisk

Läs mer

Classes och Interfaces, Objects och References, Initialization

Classes och Interfaces, Objects och References, Initialization Classes och Interfaces, Objects och References, Initialization Objekt-orienterad programmering och design (DIT953) Niklas Broberg/Johannes Åman Pohjola, 2018 Abstract class En abstract class är en class

Läs mer

TDDI14 Objektorienterad programmering

TDDI14 Objektorienterad programmering LINKÖPINGS TEKNISKA HÖGSKOLA Institutionen för datavetenskap Avdelningen för programvara och system Tommy Olsson 2015-05-27 Datortentamen i TDDI14 Objektorienterad programmering Provkod DAT1 Datum 2015-06-01

Läs mer

TDDC76 Programmering och datastrukturer

TDDC76 Programmering och datastrukturer TDDC76 Programmering och datastrukturer Arv, polymorfi och objektorienterad programmering Oskar Holmström Institutionen för datavetenskap Agenda 1 Pekare 2 Arv 3 Statisk bindning 4 Polymorfi 5 Destruktorer

Läs mer

Funktionens deklaration

Funktionens deklaration Funktioner - 1 Teknik för stora program #include #include......... cout

Läs mer

Programmera i C Varför programmera i C när det finns språk som Simula och Pascal??

Programmera i C Varför programmera i C när det finns språk som Simula och Pascal?? Programmera i C Varför programmera i C när det finns språk som Simula och Pascal?? C är ett språk på relativt låg nivå vilket gör det möjligt att konstruera effektiva kompilatorer, samt att komma nära

Läs mer

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

Collections Collections Envisa objekt Klasserna Bofstream och Bifstream Definition av metoder i klasserna Bifstream och Bofstream Klassen Streng Collections Collections "Envisa" objekt Klasserna Bofstream och Bifstream Definition av metoder i klasserna Bifstream och Bofstream Klassen Streng Klasser som skall bli "envisa" Klassen Anstelld skall

Läs mer

1 Namnkontroll (NameControl)

1 Namnkontroll (NameControl) 1 Namnkontroll (NameControl) När en ny variabel, ett objekt, en konstant o s v introduceras måste programmeraren namnge denna. Allting identifieras m h a namn. När ett program består av väldigt många komponenter

Läs mer

1 Funktioner och procedurell abstraktion

1 Funktioner och procedurell abstraktion 1 Funktioner och procedurell abstraktion Det som gör programkonstruktion hanterlig och övergripbar och överhuvudtaget genomförbar är möjligheten att dela upp program i olika avsnitt, i underprogram. Vår

Läs mer

Objektorienterad programmering med Java, Generics

Objektorienterad programmering med Java, Generics Generics i Java Generic: allmän, genersisk. På menyn på en asiatisk restaurang: Denna rätt serveras med valfritt kött, fisk eller skalddjur Bakgrund Generics i Java ger oss att skriva kod, klasser och

Läs mer

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

Innehåll. 1 Deklarationer, scope och livstid. 2 Användardefinierade typer. 4 In- och utmatning. 5 Operatoröverlagring. 6 namnrymder (namespace) Innehåll EDAF30 Programmering i C++ 2. Användardefinierade typer Sven Gestegård Robertz Datavetenskap, LTH 2016 1 Deklarationer, scope och livstid 2 Användardefinierade typer 3 Standardbibliotekets alternativ

Läs mer

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling metoder Föreläsning 2 Objektorienterad programmering DD1332 Array [modifierare] String metodnamn (String parameter) Returtyp (utdata typ) i detta fall String Indata typ i detta fall String 1 De får man

Läs mer

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

Nedan skapar vi klassen Person innehållande datamedlemmar för förnamn, efternamn, ålder, längd och vikt: 8. Objektorientering Skälet till att C++ är ett av de mest använda programspråken är att det är objektorienterat. Detta bygger vidare på begreppet struct (ursprungligen från språket C som inte är objektorienterat),

Läs mer

TDDC76 - Programmering och Datastrukturer

TDDC76 - Programmering och Datastrukturer TDDC76 - Programmering och Datastrukturer Objektorientering - Arv och polymorfi Klas Arvidsson Institutionen för datavetenskap 1 / 33 UML UML är ett grafiskt språk som (bland mycket annat) används för

Läs mer

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

Outline. Objektorienterad Programmering (TDDC77) Att instansiera en klass. Objekt. Instansiering. Åtkomst. Abstrakt datatyp. Objektorienterad Programmering (TDDC77) Föreläsning X: Klass diagram, inkapsling, arv Ahmed Rezine IDA, Linköpings Universitet Hösttermin 2017 Att instansiera en klass Objekt I Man instansierar (skapar

Läs mer

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

Innehåll. 1 Deklarationer, scope och livstid. 2 Användardefinierade typer. 4 Operatoröverlagring. 5 In- och utmatning. 6 namnrymder (namespace) Innehåll EDAF30 Programmering i C++ 2. Användardefinierade typer Sven Gestegård Robertz Datavetenskap, LTH 2017 1 Deklarationer, scope och livstid 2 Användardefinierade typer 3 Standardbibliotekets alternativ

Läs mer

DD2387 Programsystemkonstruktion med C++ Tentamen 2

DD2387 Programsystemkonstruktion med C++ Tentamen 2 DD2387 Programsystemkonstruktion med C++ Tentamen 2 Måndagen den 10 november 2014, 08:00-12:00 Introduktion Skriv dina svar på separata papper, dessa scannas in efter inlämning. Du kan skriva på båda sidor.

Läs mer

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

Det objektorienterade synsättet. Objekt. Datorprogrammet kan uppfattas som en slags modell av den verklighet programmet skall samverka med. Det objektorienterade synsättet A - 1 Objekt A - 2 Datorprogrammet kan uppfattas som en slags modell av den verklighet programmet skall samverka med. De enskilda variablerna i programmet, de s.k. objekten,

Läs mer

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

Dagens program. Programmeringsteknik och Matlab. Objektorienterad programmering. Vad är vitsen med att ha både metoder och data i objekten? Programmeringsteknik och Matlab Övning 4 Dagens program Övningsgrupp 2 (Sal Q22/E32) Johannes Hjorth hjorth@nada.kth.se Rum 4538 på plan 5 i D-huset 08-790 69 02 Kurshemsida: http://www.nada.kth.se/kurser/kth/2d1312

Läs mer

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Felsökning. Datatyper. Referenstyper. Metoder / funktioner

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Felsökning. Datatyper. Referenstyper. Metoder / funktioner 732G11 Linköpings universitet 2011-01-21 1 2 3 4 5 6 Skapa program Kompilera: Källkod Kompilator bytekod Köra: Bytekod Virtuell maskin Ett riktigt program Hej.java class Hej { public static void main (

Läs mer

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

Programsystemkonstruktion med C++: Övning 1. Karl Palmskog september 2010 Programsystemkonstruktion med C++: Övning 1 Karl Palmskog palmskog@kth.se september 2010 Programuppbyggnad Klassens uppbyggnad en C++-klass består av en deklaration och en definition deklaration vanligtvis

Läs mer

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

Första exemplet. Kompilator & länkare. Projekt. Övning 1, Ögrupp 4, Programsystemkonstruktion med C++, Ronnie Johansson, Övning 1, Ögrupp 4, Programsystemkonstruktion med C++, 2003 09 11 Ronnie Johansson, rjo@nada.kth.se Vi kommer att titta på: Kompilering och länkning make och Makefile Preprocessordirektiv main() funktionen

Läs mer

Trädtraversering. Binärt träd. Trädtraversering djupet-först. Trädtraversering bredden-först

Trädtraversering. Binärt träd. Trädtraversering djupet-först. Trädtraversering bredden-först TDDI14 Objektorienterad programmering Fö: Binära träd, uttrycksträd 69 Binärt träd TDDI14 Objektorienterad programmering Fö: Binära träd, uttrycksträd 70 Trädtraversering struct Tree_Node Tree_Node(const

Läs mer

Tentamen EDAF30 Programmering i C++

Tentamen EDAF30 Programmering i C++ LUNDS TEKNISKA HÖGSKOLA 1(6) Institutionen för datavetenskap Tentamen EDAF30 Programmering i C++ 2016 01 11, 8.00 13.00 Hjälpmedel: En valfri C++-bok. OH-bilderna från föreläsningarna är inte tillåtna.

Läs mer

Typkonvertering. Java versus C

Typkonvertering. Java versus C Typer Objektorienterad programmering E Typkonvertering Typkonvertering Satser: while, for, if Objekt Föreläsning 2 Implicit konvertering Antag att vi i ett program deklarerat int n=3; double x = 5.2; Då

Läs mer

F4. programmeringsteknik och Matlab

F4. programmeringsteknik och Matlab Programmeringsspråk Föreläsning 4 programmeringsteknik och Matlab 2D1312/ 2D1305 Introduktion till Java Kompilering, exekvering, variabler, styrstrukturer 1 Ett program är en eller flera instruktioner

Läs mer

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

Föreläsning 5-6 Innehåll. Exempel på program med objekt. Exempel: kvadratobjekt. Objekt. Skapa och använda objekt Skriva egna klasser Föreläsning 5-6 Innehåll Exempel på program med objekt Skapa och använda objekt Skriva egna klasser public class DrawSquare { public static void main(string[] args) { SimpleWindow w = new SimpleWindow(600,

Läs mer