Föreläsning Mallar
|
|
- Helen Månsson
- för 6 år sedan
- Visningar:
Transkript
1 *:85/ID200V C++ HT07 Föreläsning 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 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 162 1
2 Abstraktionsnivåer Mallar Klasser (eller funktioner), alltså typer Objekt (eller anrop) Bild 163 Funktionsmallar - exempel // class kan användas istället för typename void swap(typ& x, TYP& y){ TYP slask=x; x=y; y=slask; 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 164 2
3 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 bör större medlemsfunktioner definieras utanför klassdefinitionen, men Bild 165 Vector<TYP>::Vector(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]; template <typename 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 bara har lokal betydelse i varje mall Bild 166 3
4 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(); Instansiering av klassmallar är explicit - mallargumenten måste anges. Medlemsfunktioner instansieras först vid kompilering av ett program som anropar dem! Vector<Person> pvec; // Förutsätter att Person har en default-ktor pvec.push_back(person( Jozef, 53)); pvec.push_back(person( Stefan, 61)); Person pm = pvec.max(); // Fel, instansiering av // Vector<Person>::max // misslyckas, det finns ingen operator> // för Person! Bild 167 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 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. Det finns även förslag på införande av sådana mekanismer i nästa C++-standard. Bild 168 4
5 Mer om klassmallar Det finns nu ingenting som heter Vector, överallt där man vill använda mallen måste den specialiseras, antingen med en specifik typ, t.ex. Vector<int> eller med mallargumentet till den enhet som använder Vector<TYP> - denna måste alltså enhet också vara en mall: void print_vector(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 en godtycklig specialisering av en mall som ett argument 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 169 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 kan definitionen av copy-konstruktorn göras så här 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]; 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> Stringvector; 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 behov av sådana konstruktioner Bild 170 5
6 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 171 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<typename 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 172 6
7 Mallspecialiseringar är olika typer Mallspecialiseringar är helt olika typer som inte har något med varandra att göra. Exempel: Klass<> class Klass{ TYP data; Klass<string> Klass<int> Klass(TYP d):data(d){ void visa() const { cout << data << endl; ks ki ; 42 int main(){ Klass<std::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. Obs! att medlemsfunktionen visa() ser olika ut i Klass<string> och Klass<int>, det är olika operator<< som anropas! How many roads must a man walk down? Bild 173 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<std::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 174 7
8 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 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 175 Exempel ur inluppen, forts. Där man vill ha ett godtyckligt Action-objekt kan man nu ha en Action_base *: class Button : public Component{ std::string caption; Action_base *action; Button(, string cap, Action_base *a):, caption(cap), action(a){ bool handle_event(event eve){ 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: Button* b=new Button(, new Action<Value>(&v, &Value::oka)); (något förändrat vid användning av referensräknande smarta pekare ) Bild 176 8
9 Hjälpfunktioner för implicit instansiering av klassmallar Instansiering av funktionsmallar är implicit - kompilatorn gissar sig till mallargumenten ur funktionsanropet ( argumentdeduktion ). Instansiering av klassmallar är explicit - mallargumentet måste anges efter klassnamnet: Button *b = 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: Button* b = new Button(, mk_action(&v, &Value::oka)); Bild 177 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<typename TYP> void funk(typ *pek){ TYP temp = *pek; ; int *ipek; funk(ipek); Funktionsargumentet är en int * så mallargumentet är int template<typename 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 178 9
10 Explicit instansiering av funktionsmallar Ibland framgår inte mallargumenten ur funktionsargument. Detta inträffar 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 <typename RET, typename 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); Explicit instansiering av funktionsmallar kan även användas för att påtvinga en instansiering där de aktuella funktionsargumenten inte exakt överenstämmer med mallargumenten (för att påtvinga en implicit konvertering): str = funk<string, double>(13); Bild 179 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<typename 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
11 Överlagrade funktionsmallar Funktionsmallar kan överlagras med andra funktionsmallar och med vanliga funktioner. Det är den mest specialiserade funktionen som kommer att anropas (efter eventuell instansiering). void funk(typ x){ cout << funk<typ> << endl; Vi återkommer till specialiserade klassmallar void funk(typ *x){ cout << funk<typ *> << endl; senare 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 181 Överlagring av funktionsmallar, exempel Ibland inträffar det att en generell mall är bra för de flesta men inte alla typer, d.v.s. att man för en viss specifik typ (eller familj av typer) vill ange ett alternativt källkodsmönster. Man kan då skapa alternativa mallar som kompilatorn skall välja om mallen instansieras med denna specifika typ (eller en typ från denna familj av typer). Exempel: generell mall för swap-operationen: void swap(typ& x, TYP& y){ TYP slask=x; x=y; y=slask; För byte mellan två Vector<>-objekt med värdesemantik (bl. a. överlagrad operator=) är detta ineffektivt, elementarrayer allokeras, kopieras och avallokeras i onödan. Man kan då skapa en mall för swap som är mer specialiserad än den generella mallen genom att ange funktionsargumenten som referenser till Vector<>specialiseringar. 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; Obs! Fel, försöker jobba på privata data - se nästa bild Bild
12 Rättelse till föregående bild Mallen för swap-funktionen på förra bilden är felaktig eftersom en Vectors data är privata och swap-funktionen inte kan komma åt dem. Detta kan lösas genom att swap-funktionen friend-deklareras i Vector (måste göras på ett speciellt sätt, se bild 186) eller att Vector-klassen utrustas med en medlemsfunktion för byte med ett annat Vector-objekt och denna funktion anropas från mallen (så görs det i STL): class Vector{ void swap(vector& other); ; template<typename TYP> void Vector<TYP>::swap(Vector& other){ int s=siz, c=cap; TYP *a = arr; siz=other.siz; cap=other.cap; arr=other.arr; other.siz=s; other.cap=c; other.arr=a; void swap(vector<typ>& x, Vector<TYP>& y){ x.swap(y); Bild 183 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
13 Exempel från inluppen, forts. Vi kan dock underlätta för tillämpningsprogrammerare genom att skapa överlagrade funktionsmallar för hjälpfunktioner: template <typename 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ämpningen kan nu skapa alla sina Action<>-objekt på samma sätt : void quit() { std::exit(0); Button* b1=new Button(, mk_action(&v, &Value::oka)); Button* b2=new Button(.., mk_action( Minska,&v,&Value::minska)); Button *b3=new Button(, mk_action(quit)); Bild 185 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 <typename TYP2> friend void funk(const TYP2&); Bild
14 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: template <class TYP> void swap(typ& x, TYP& y); template <class TYP> class Vector; template <class TYP> void swap(vector<typ>& x, Vector<TYP>& y); Den specialiserade friend-deklarationen kräver att mallen för funktionen redan är deklarerad. Men deklaration av mallen kräver att Vector<> redan är deklarerad template <class TYP> class Vector{ friend void swap<typ>(vector<typ>&, Vector<TYP>&); ; template <class 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 187 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){ ; template <typnamn TYP> 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
15 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 <typename PEKTYP> // Deklaration Vector(PEKTYP pek1, PEKTYP pek2); ; // Definition template <typename PEKTYP> Vector<TYP>::Vector(PEKTYP pek1, PEKTYP pek2): siz(0), cap(10), arr(new TYP[cap]) { while (pek1!= pek2) push_back(*pek1++); Bild 189 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, arr+arrsize); // Vector<int>::Vector(int *, int *) Bild
16 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 191 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 <typename ANNANTYP> operator Alfa<ANNANTYP>(); ; template <typename ANNANTYP> Alfa<TYP>::operator Alfa<ANNANTYP>(){ return ett temporärt Alfa<ANNANTYP>-objekt konstruerat ur detta Alfa<TYP>-objekt Bild
17 Mall för pekarklass för polymorfa objekt class null_pointer; // Undantagsklass, visas senare template <typename T> class Ptr{ T *ptr; int *count; template<typename 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 <typename OTHERTYPE> // Konvertering till Ptr för annan operator Ptr<OTHERTYPE>(); // typ (basklasstyp) ; Bild 193 Implementering av vissa medlemmar i Ptr-mallen template <typename T> // Den nya privata konstruktorn Ptr<T>::Ptr(T *p, int *c):ptr(p), count(c){ if (ptr) (*count)++; template <typename T> // Den publika konstruktorn Ptr<T>::Ptr(T *p) throw(std::bad_alloc): ptr(p), count(ptr?new int(1):0){ // Konverteringsoperator till Ptr för annan typ template <typename OTHERTYPE> Ptr<TYP>::operator Ptr<OTHERTYPE>(){ Se OH return Ptr<OTHERTYPE>(ptr, count); för implementering av andra medlemmar template <typename T> // Konverteringsoperator till vanlig pekare Ptr<T>::operator T*() const throw(){ return ptr; Bild
18 Implementering av vissa medlemmar i Ptr-mallen, forts. template <typename T> T& Ptr<T>::operator*() throw(null_pointer){ if (ptr == 0) throw null_pointer(); return *ptr; template <typename T> T* Ptr<T>::operator->() throw(null_pointer){ if (ptr == 0) throw null_pointer(); return ptr; const-varianter implementeras på samma sätt Kräver #include <stdexcept> class null_pointer : public std::runtime_error{ null_pointer() : runtime_error("null_pointer"){ null_pointer(std::string msg): runtime_error("null_pointer" + msg){ ; Bild 195 Kommentarer till Ptr-mallen En bra och generell mall för referensräknande pekarklasser är svår att utforma (vilket är anledningen till att någon sådan inte finns i standardbiblioteket). Som någon har sagt: smarta pekare kan vara riktigt smarta med de kan inte vara riktiga pekare. Det kan uppkomma problem med användning av den föreslagna Ptr-mallen som jag inte inser nu, jag kommer i så fall att meddela problemen i FC (och förhoppningsvis en lösning). Ett problem som jag ser nu är att dynamic_cast inte fungerar på dessa pekarklasser, dynamic_cast vill ju ha en vanlig pekare att testa det utpekade objektet med. Detta kan lösas på många sätt men inget som är transparent för användaren. Vid behov återkommer jag i FC med förslag på en lösning. Bild
19 En polymorfisk klass för användning med Ptr class Bird : public Animal{ Fabriksfunktion static Ptr<Bird> create(string name, double ws); double get_wingspan() const; protected: Bird(string name, double ws); private: double wingspan; Bird(const Bird& other); const Bird& operator=(const Bird& other); Bird* operator&(); const Bird* operator&() const; ; Ptr<Bird> Bird::create(string name, double ws){ return Ptr<Bird>(new Bird(name, ws)); Bird::Bird(string name, double ws): Animal(name), wingspan(ws) { Påtvinga användning av create() för objektskapande, tillåt subklasser Förbjud kopiering, adresstagning osv. Implementeras inte! Det räcker att det görs i rotklassen double Bird::get_wingspan() const { return wingspan; Bild 197 Minns klassmallen Vector<>? Åter till mallar - klassmallar #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 ; Bild
20 Vector<>, definitioner av medlemsfunktioner Vector<TYP>::Vector(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]; template <typename 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 Bild 199 Explicit mallspecialisering En generell mall anger källkodsmönstret som är parametriserat med (oftast) typer. Den kan instansieras med en godtycklig specifik typ, en sådan mallinstans kallas en specialisering. Ibland inträffar det att det generella källkodsmönstret är bra för de flesta men inte alla typer, d.v.s. att man för en viss specifik typ (eller familj av typer) vill ange ett alternativt källkodsmönster. Man kan då skapa ett alternativt källkodsmönster som kompilatorn skall välja om mallen instansieras med denna specifika typ (eller en typ från denna familj av typer). Detta kallas explicit specialisering eller användardefinierad specialisering. Det kan jämföras med funktionsöverlagring där kompilatorn väljer den funktion som bäst passar argumenttyperna vid ett anrop. För funktionsmallar har vi sett hur det kan göras genom överlagring med mer specialiserade mallar eller t.o.m. med vanliga funktioner (se OH ). För klassmallar finns det speciell syntax och möjlighet till (fullständig) explicit specialisering av hel klass (fullständig) explicit specialisering av enskilda medlemmar partiell explicit specialisering Bild
21 Fullständig explicit specialisering av hel klass Antag följande klassmall (syntaktiskt exempel): /* alfa.h */ #ifndef ALFA_H #define ALFA_H template <typename T> class Alfa{ T data; Alfa(const T& d); bool operator<(const Alfa<T>& other) const; ; template <typename T> Alfa<T>::Alfa(const T& d):data(d){ template <typename T> bool Alfa<T>::operator<(const Alfa<T>& other) const{ return data < other.data; #endif Bild 201 Fullständig explicit specialisering av hel klass, forts. #include alfa.h int main(){ Alfa<int> ai1(3), ai2(17); if (ai1 < ai2) // Funkar bra. Alfa<char *> as1( stefan ), as2( jozef ); if (as1 < as2) // Funkar dåligt, jämför pekare!. Man kan göra en explicit specialisering av klassen Alfa för typen char *, se nästa bild. Bild
22 Fullständig explicit specialisering av hel klass, forts. /* alfa.h */ #ifndef ALFA_H #define ALFA_H // Precis som på bild 216 template<> // Anger att det är en specialisering class Alfa<char *>{ char* data; Alfa(const char *str); bool operator<(const Alfa<char *>& other) const; ~Alfa(); ; #endif #include "alfa.hpp" #include <cstring> using namespace std; Definitioner av medlemsfunktionerna är nu vanliga funktioner och måste göras i en.cpp-fil Alfa<char *>::Alfa(const char *str):data(new char[strlen(str)+1]){ strcpy(data, str); bool Alfa<char *>::operator<(const Alfa<char *>& other) const{ return strcmp(data, other.data)<0; Alfa<char *>::~Alfa() { delete [] data; Bild 203 Explicit specialisering av klassmallmedlemmar Enskilda medlemsfunktioner i en klassmall kan specialiseras. Exempel: medlemsfunktionen max() kommer inte att fungera väl för Vector<char *> eftersom den då kommer att jämföra pekare - kan ersättas med en max-funktion som använder strcmp: template<> char * Vector<char *>::max() const { char *m = arr[0]; for(int i=1; i<siz; i++) if (strcmp(arr[i], m) > 0) m = arr[i]; return m; Struligt nog är detta inte längre en mall utan en funktion - måste därför ligga i en.cpp-fil. Bild
23 Partiell explicit specialisering Ibland vill man ange en explicit specialisering av en hel klass, t.ex. för en viss familj av typer. Detta kan också göras med explicit (ev. partiell) specialisering. Obs! att alla klassmedlemmar i specialiseringen måste då definieras, även de som är exakt som i den generella mallen. Exempel (endast syntaktiskt, brukar inte skötas så): säg att vi vill att Vector<> som instansierats med pekartyper skall ta bort inte bara sina element (pekarna) utan även de utpekade objekten: template <class TYP> // Explicit partiell specialisering av Vector<> class Vector<TYP *>{ int int, cap; TYP **arr; ~Vector(); ; template <class TYP> // Motsvarande på andra ställen vid borttag Vector<TYP *>::~Vector(){ for(int i=0; i<siz; i++) delete arr[i]; delete [] arr; Bild 205 Förklaring till Stroustrups användning av void * Ett problem med föregående exempel är att klassmallen kommer att instansieras på nytt för varje pekartyp som Vector<> instansieras med. Detta fungerar, men ledar till onödigt stora objektkoder med kanske många upprepningar av exakt likadan maskinkod. Just för pekartyper kan detta lösas genom att göra en explicit specialisering för void * och sedan skapa mallen för en subklass - parametriserad med pekartypen: template<> class Vector<void *>{ int siz, cap; void **arr; void *& operator[](int index) { return arr[index]; ; template <class TYP> class Vector<TYP *> : private Vector<void *>{ typedef Vector<void *> Base; TYP *& operator[](int index) { return Base::operator[](index); ; Bild
24 Anpassning av återanvändbara klasser Säg att vi vill skapa en mall för en sorterad datastruktur för godtycklig elementtyp. Det innebär som vanligt att tillämpningsprogram måste kunna ange hur elementen skall jämföras. Det finns tre tekniker för detta: 1. Imperativ (?) lösning: tillämpningsprogrammet installerar en pekare till en jämförelsefunktion i datastrukturobjektet. Används i C samt ibland i Java (komparator-objekt). Innebär (onödig) flexibilitet under exekvering, med tillhörande ineffektivitet. 2. Objektorienterad lösning: elementtypen måste vara av en subklass till en basklass som har deklarerat en virtuell jämförelsefunktion. Subklassen definierar sin egen jämförelsefunktion som kan anropas av datastrukturen p.g.a. dynamisk bindning. Används i Java (compareto-metoden i Comparable-klasser). Innebär också run-time-flexibilitet med tillhörande kostnad 3. Generisk lösning: jämförelseoperationen anges som mallargument. Detta innebär att jämförelseoperationen kompileras in i koden för den aktuella instansen av datastrukturen. Detta ger flexibilitet vid utformning av mallen, men bestäms vid kompilering av tillämpningsprogrammet och kostar inget vid exekveringen. Bild 207 Anpassning genom mallparametrar Exempel på jämförelseoperation som mallargument: template <class TYP, class BEFORE> class Sorted{ int siz, cap; TYP *arr; BEFORE bef; Sorted(): siz(0), cap(10), arr[new TYP[cap]){ void insert(const TYP& value); ; template<class TYP, class BEFORE> void Sorted<TYP, BEFORE>::insert(const TYP& value) { for(int i = siz; i > 0 && bef(value, arr[i-1]); i--) arr[i] = arr[i-1]; arr[i] = value; // Anta för enkelhetens skull att utrymme finns ++siz; Bild
25 Anpassning genom mallparametrar, forts. Operationen BEFORE kan göras som en funktionsobjektsklass: struct Yngre { bool operator()(const Person& p1, const Person& p2){ return p1.age < p2.age; ; int main(){ Sorted<Person, Yngre> pers_lista; Den genererade klassen Sorted<Person, Yngre> kommer att se ut som om den skapades av följande klassdefinition: class Sorted{ int siz, cap; Person *arr; Yngre bef; Sorted(): siz(0), cap(10), arr[new Person[cap]){ void insert(const Person& value); ; void Sorted<Person, Yngre>::insert(const Person& value) { for(int i = siz; i > 0 && bef(value, arr[i-1]); i--) arr[i] = arr[i-1]; arr[i] = value; ++siz; Bild 209 Funktion som jämförelse Man kan givetvis förbereda Sorted<> till att använda en funktion istället för ett funktionsobjekt som jämförelsekriterium. Obs dock att olika booleska funktioner har samma typ, som mallargument kan man ange att Sorted<> ska ha en funktionspekare men inte vilken funktion som ska installeras - detta måste göras genom t.ex. ett argument till konstruktorn: template <class TYP, class BEFORE> class Sorted{ int siz, cap; TYP *arr; BEFORE bef; Sorted(BEFORE b): siz(0), cap(10), arr(new TYP[cap]), bef(b){ void insert(const TYP& value); ; template<class TYP, class BEFORE> void Sorted<TYP, BEFORE>::insert(const TYP& value) { for(int i = siz; i > 0 && bef(value, arr[i-1]); i--) arr[i] = arr[i-1]; arr[i] = value; ++siz; Bild
26 Funktion som jämförelse, forts. Nu kan operationen BEFORE kan göras som en funktion, t.ex. bool yngre(const Person& p1, const Person& p2) { return p1.age < p2.age; typedef bool(*bef)(const Person&, const Person&); int main(){ Sorted<Person, BEF> pers_lista(yngre); eller som tidigare med funktionsobjekt: Sorted<Person, Yngre> pers_lista(yngre()); Det finns flera föredelar med att använda funktionsobjekt här och inte funktionen: en funktion kan inte kompileras in, det som läggs in i den genererade klassen är en funktionspekare. När kompilatorn ser en funktionspekare kan den inte vara säker på att pekaren inte förändras mellan anropen för att peka ut en annan funktion, den kan alltså inte optimera användningen av funktionen t.ex. genom inlining. Med ett funktionsobjekt däremot ser kompilatorn ett objekt vars medlemsfunktion används, det kan inte bli ett annat objekt eller en annan funktion och användningen kan därför optimeras alla booleska funktioner med två const-referenser till Person-objekt har samma typ. Det gör att två Sorted<Person, BEF> med olika jämförelsefunktioner har samma typ och kan t.ex. tilldelas till varandra eller jämföras, vilket inte borde vara fallet Bild 211 Default-argument för mallar Liksom för funktionsargument kan man ange default- värde för klassmallargument (dock inte för funktionsmallar): template<class TYP> struct Less{ bool operator()(const TYP& x, const TYP& y){ return x < y; ; template <class TYP, class BEFORE = Less<TYP> > class Sorted{ int siz, cap; TYP *arr; BEFORE bef; Sorted(BEFORE b=less<typ>()): siz(0), cap(10), arr[new TYP[cap]), bef(b){ void insert(const TYP& value); Om operator< är definierad för elementtypen och man vill ha stigande sorteringsordning så behöver inte jämförelseoperationen anges vid deklaration: Sorted<Person> pers_lista; Bild
27 Exempel från std: basic_string<> I många situationer kan mallar göras mer generella genom att ange olika egenskaper för t.ex. elementtypen som parametrar till mallen. Sådana egenskaper brukar då samlas som statiska medlemsfunktioner i en s.k. traits-class. Exempel: typen string är egentligen en instansiering av mallen basic_string<> vars parametrar är teckentypen, dess egenskaper ( traits ) och minneshantering: namespace std{ template <class chart = char, // Teckentypen class traits = char_traits<chart>, // Hur tecken jämförs class allocator = allocator<chart> > // Hur man allokerar class basic_string{ ; typedef basic_string<char> string; Man kan alltså lätt skapa en strängtyp där tecknen t.ex. jämförs på annat sätt än vad som är inbyggt för typen char (se nästa bild). Samtidigt kostar det mycket lite vid exekveringen (behövde man anropa en riktig funktion vid varje teckenjämförelse skulle det bli oacceptabelt ineffektivt). Bild 213 Exempel: en egen char_traits Säg att vi behöver en strängtyp där tecknens skiftläge (gemena eller versaler) inte påverkar jämförelser: #ifndef ICSTRING_H #define ICSTRING_H #include <string> #include <cctype> struct ignore_case_traits: public std::char_traits<char>{ static bool eq(const char& c1, const char& c2){ return std::toupper(c1) == std::toupper(c2); static bool lt(const char& c1, const char& c2){ return std::toupper(c1) < std::toupper(c2); static int compare(const char *s1, const char *s2, size_t n){ size_t i; for(i=0; i<n-1 &&!eq(s1[i], s2[i]); ++i) ; return s1[i]-s2[i]; ; typedef std::basic_string<char,ignore_case_traits> icstring; #endif Bild
Operatorer för medlemspekare
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
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
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
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
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
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
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
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
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
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
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
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
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
*: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
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
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
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
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
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
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 + - * / % ^ & ~! > = += -= *= /= %= ^= &= = = < > = ==!= && ++ -- -> ->*, [ ]
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
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
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
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.
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
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
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
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.
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.
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
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
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
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.
Innehåll. 1 Funktionsmallar. 2 Pekare och konstanter. 3 Typomvandlingar. struct Name { string s; //... };
Innehåll EDAF30 Programmering i C++ 6. Typer, pekare och konstanter. 1 Sven Gestegård Robertz Datavetenskap, LTH 2016 2 Pekare och konstanter Operatorn -> Konstanter 3 Typomvandlingar 6. Typer, pekare
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
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. 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
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
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
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
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.
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
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.
Innehåll. Typomvandlingar (casting) Implicita Typomvandlingar. Typomvandlingar (casting) Implicita Typomvandlingar
Innehåll EDAF30 Programmering i C++ 9. Polymorfism och arv Sven Gestegård Robertz Datavetenskap, LTH 2016 1 Typomvandling 2 Klasser Polymorfism och arv Konstruktorer och destruktorer Tillgänglighet Arv
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
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
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
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
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:
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
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
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
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
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,
Ö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++
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
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
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
Tentamen EDAF30 Programmering i C++
LUNDS TEKNISKA HÖGSKOLA 1(8) Institutionen för datavetenskap Tentamen EDAF30 Programmering i C++ 2016 05 13, 8.00 13.00 Hjälpmedel: En valfri C++-bok. OH-bilderna från föreläsningarna är inte tillåtna.
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
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 Klasser - speciella medlemsfunktioner Eric Elfving Institutionen för datavetenskap En klass ansvarar ofta för en resurs. Ibland är resursen så enkel som en datamedlem
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
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
Generell (template) programmering. Effektiv C++ Slutliga tips Genomgång av gammal tenta. Daniel Aarno Allt som fungerar som x ÄR x
Generell (template) programmering Funktionsobjekt och funktionspekare Iteratorer Algoritmer Effektiv C++ Slutliga tips Genomgång av gammal tenta Daniel Aarno bishop@kth.se 2 int compare(int i1, int i2)
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
allokeras på stacken dynamiskt new delete
Minneshantering Lokala objekt allokeras på stacken och har kort livslängd Objekt med längre livslängd måste allokeras dynamiskt på heapen (free store) Dynamisk allokering görs med new och delete Statiska
Tillämpad programmering
Tillämpad programmering C++ objekt Johan Montelius 1 struct struct Person { string name; int age; ; Person p; p.name = Joe ; p.age = 42; cout
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),
Minneshantering. Minneshantering. Minneshantering. Undvik pekare
Minneshantering Lokala objekt allokeras på stacken och har kort livslängd Objekt med längre livslängd måste allokeras dynamiskt på heapen (free store) Dynamisk allokering görs med new och delete Statiska
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
Kapitel 4 - Mallar. Kapitel 4. Introduktion till mallar STL. 2D1387 Programsystemkonstruktion med C++ 1
Kapitel 4 Introduktion till mallar STL 2D1387 Programsystemkonstruktion med C++ 1 Kapitel 4 - Klassmallar, funktionsmallar och STL Funktionsmallar Klassmallar Mallar för medlemmar Specialisering Standardbiblioteket
Kapitel 4. Funktionsmallar. Mallar. Introduktion till mallar STL
Kapitel 4 Introduktion till mallar STL Kapitel 4 - Klassmallar, funktionsmallar och STL Funktionsmallar Klassmallar Mallar för medlemmar Specialisering Standardbiblioteket för mallar (STL): Namnrymden
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
Objektorienterad programmering i Java
Objektorienterad programmering i Java Föreläsning 4 Täcker i stort sett kapitel 6 i kursboken Java Software Solutions 1 Läsanvisningar Den här föreläsningen är uppbyggd som en fortsättning av exemplet
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
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
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
Föreläsning 8 - del 2: Objektorienterad programmering - avancerat
Föreläsning 8 - del 2: Objektorienterad programmering - avancerat Johan Falkenjack johan.falkenjack@liu.se Linköpings universitet Sweden December 4, 2013 1 Innehåll Arv och andra viktiga begrepp Abstrakta
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..........................................
Objektorienterad Programmering (TDDC77)
Objektorienterad Programmering (TDDC77) Föreläsning X: Klass diagram, inkapsling, arv Ahmed Rezine IDA, Linköpings Universitet Hösttermin 2017 Outline Instansiering Åtkomst Abstrakt datatyp UML Överlagring
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.
Innehåll. EDAf30: Programmering i C++, 7.5 hp. EDAf30: Programmering i C++, 7.5 hp Viktiga skillnader mot Java
Innehåll EDAF30 Programmering i C++ 1. Introduktion 1 Om kursen Sven Gestegård Robertz Datavetenskap, LTH 2016 2 Presentation av C++ Historik Inledning Datatyper och variabler 1. Introduktion 2/1 Viktiga
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
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
Vad är en klass? Övning 2. Konstruktorer. ffl copy-konstruktorn tar en instans av klassen som. ffl default-konstruktorn tar inga argument och kan
Vad är en klass? Övnin 2 Daens ämne är klasser och hur de hanteras. Vi kommer att bya upp ett exempel stevis och illustrera en hel del möjliheter, men också problem och saker man bör vara vaksam på. ffl
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
Vem är vem på kursen. Objektorienterad programvaruutveckling GU (DIT011) Kursbok Cay Horstmann: Big Java 3rd edition.
Institutionen för Datavetenskap Göteborgs universitet HT2009 DIT011 Vem är vem på kursen Objektorienterad programvaruutveckling GU (DIT011) Kursansvarig : Katarina Blom, tel 772 10 60 Rum: 6126 (E-huset)
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
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
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
Kapitel 4. Funktionsmallar. Mallar. Introduktion till mallar STL
Kapitel 4 Introduktion till mallar STL Kapitel 4 - Klassmallar, funktionsmallar och STL Funktionsmallar Klassmallar Mallar för medlemmar Specialisering Standardbiblioteket för mallar (STL): Namnrymden
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
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
Algoritmbiblioteket (STL) Designstrategi Generiska algoritmer som fungerar på godtyckliga samlingsdatatyper, vilka har iteratorer.
Algoritmbiblioteket (STL) (f.d.) Standard Template Library Samlingstyper (containers) Algoritmer Funktionsobjekt Adaptrar Designstrategi Generiska algoritmer som fungerar på godtyckliga samlingsdatatyper,
Generiska konstruktioner. Kursbokens kapitel 13
Generiska konstruktioner Kursbokens kapitel 13 1 Vad är en generisk konstruktion? Generisk står för; allmän eller generell En generisk konstruktion kan användas för olika typer av data Med hjälp av templates
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
Arv: Fordonsexempel. Arv. Arv: fordonsexempel (forts) Arv: Ett exempel. En klassdefinition class A extends B {... }
En klassdefinition class A extends B {... Arv definierar en klass A som ärver av B. Klassen A ärver alla fält och metoder som är definierade för B. A är en subklass till B. B är en superklass till A. class
Den som bara har en hammare tror att alla problem är spikar
Introduktion Föreläsning (Weiss kap. -4) Många begrepp blir det Introduktion till kursen Exempel: Datastrukturen mängd Generiska Den som bara har en hammare tror att alla problem är spikar Vilken
UML. Klassdiagr. Abstraktion. Relationer. Överskugg. Överlagr. Aktivitetsdiagram Typomv. Typomv. Klassdiagr. Abstraktion. Relationer.
Översikt Klasshierarkier UML klassdiagram Relation mellan klasser mellan klasser och objekt Association ning ing andling Programmering tillämpningar och datastrukturer 2 UML UML Unified Modeling Language