Operatorer för medlemspekare
|
|
- Ulla Håkansson
- för 6 år sedan
- Visningar:
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
*: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
*: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
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
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
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
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
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
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.
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
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
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
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
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.
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
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
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.
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
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
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
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
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
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
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
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
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
Ö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++
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
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
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
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
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
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
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 + - * / % ^ & ~! > = += -= *= /= %= ^= &= = = < > = ==!= && ++ -- -> ->*, [ ]
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
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
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
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
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
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
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
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
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.
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
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
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
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
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
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.
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
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
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
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
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
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
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Ö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
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
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
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
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
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:
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
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
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..........................................
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
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
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
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
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.
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
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
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
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
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
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
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
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
Funktionens deklaration
Funktioner - 1 Teknik för stora program #include #include......... cout
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
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
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
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
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
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
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
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),
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
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
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
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.
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,
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
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 (
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
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
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
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.
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å
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
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,