31
Föreläsning 6

Föreläsning 6

  • Upload
    tuyet

  • View
    51

  • Download
    0

Embed Size (px)

DESCRIPTION

Föreläsning 6. Klassmallar. Templates kan givetvis även användas för klasser Standardutseende. template < class T> // Klassdefinition (*.h) class C { returtyp metod(parametrar…); ... };. template < class T> // Def. av metod (*.h) returtyp C::metod(parametrar…) { ... }. - PowerPoint PPT Presentation

Citation preview

Page 1: Föreläsning  6

Föreläsning 6

Page 2: Föreläsning  6

Klassmallar

• Templates kan givetvis även användas för klasser– Standardutseende

template<class T> // Klassdefinition (*.h)class C { returtyp metod(parametrar…); ...};

template<class T> // Def. av metod (*.h)returtyp C<T>::metod(parametrar…){ ... }

Page 3: Föreläsning  6

Templates i templates

• ”Templatiserade” klasser kan ta templates som argument– std::vector<Point<float> > vektor;– Observera; mellanslag mellan de

avslutande hakarna!

Page 4: Föreläsning  6

Egna Namespaces

• För att skapa ett eget namespace att lägga klasser i använder man nyckelordet namespace– Standardutseende

Namespace jms{ template<class T> class Matrix { returtyp metod(parametrar…); ... };}

Page 5: Föreläsning  6

Egna Namespaces

• 3 olika sätt att komma åt klassen Matrix– jms::Matrix<int> matrix;

• Använder uttryckligen en klass i ett specifikt namespace– using namespace jms;Matrix<int> matrix;

• Använder hela jms namespace (risk för kollisioner)– using jms::Matrix;Matrix<int> matrix;

• Använder endast en delmängd av jms namespace (Matrix)

Page 6: Föreläsning  6

typeid

• I vissa fall vill man kunna avgöra ett objekts egentliga klass– Detta kan lösas med operatorn typeid

void fordonsinfo(Fordon * fp){ if (typeid(*fp) == typeid(Personbil)) cout << ”fp är en personbil” << endl; else if (typeid(*fp) == typeid(Buss)) cout << ”fp är en buss” << endl; else if (typeid(*fp) == typeid(Lastbil)) cout << ”fp är en personbil” << endl;};

Page 7: Föreläsning  6

Upcast• Vi har tidigare sett att man kan behandla

specialiserade klasser på samma sätt som mindre specialiserade klasservoid main(){ Personbil bil; // Personbil skickas som ett Fordon fordonsinfo(&bil); }

void fordonsinfo(Fordon * fp){ // Vi kan anropa Fordons alla medlemmar // Vi kan INTE anropa Personbils medlemmar!};

Page 8: Föreläsning  6

typecast

• Vi kan använda explicit typomvandling för att konvertera åt andra hållet– Vi kan konvertera från vilken klass som

helst till annan valfri klass– Ingen säker metod eftersom vi teoretiskt

sett kan typomvandla från ett ”Däggdjur” till en ”Bil” vilket ger en överhängande risk för programkrasch

Page 9: Föreläsning  6

typecast

void main(){ Horse horse; Car * car1 = &horse; // kompilatorn varnar Car * car2 = (Car*)&horse; // accepteras car2->ShiftGear(3); // PROGRAMKRASCH!}

Page 10: Föreläsning  6

Downcast• För att göra en typsäker typomvandling finns i

C++ specialoperatorn dynamic_cast– C++ kontrollerar att objektet verkligen är av rätt typ

för att en säker typomvandling skall kunna ske– Klassen måste vara polymorf (virtuella metoder)void fordonsinfo(Fordon * fp){ Personbil * bil; bil = dynamic_cast<Personbil*>(fp);

if (bil) cout << ”fp är en Personbil”; else cout << ”felaktig typomvandling”;}

Page 11: Föreläsning  6

Felhantering

• Felhantering i C är ganska besvärlig– Oftast returneras felmeddelanden från

funktioner. Returvärdena måste sedan kontrolleras samt hantera eventuella fel

– Om en funktion returnerar ett objekt är det svårt att bestämma när ett fel har uppstått.

– Kan ge konstiga konstruktioner

Page 12: Föreläsning  6

Exempel (felhantering)

void main(){ // division med noll! float resultat = dividera(5.0f, 0.0f); // vad är ett felaktigt returvärde i // detta fall?}

float dividiera(float taljare, float namnare){ // hur hanterar vi division med noll? return taljare/namnare;};

Page 13: Föreläsning  6

Exempel (felhantering C)

void main(){ int resultat; int retur = dividera(5.0f, 0.0f, &resultat); if (retur = 0) // Division med noll!!}

int dividiera(float taljare, float namnare, float result){ if (taljare == 0) return 0; *result = taljare/namnare; return 1;};

Page 14: Föreläsning  6

Exempel (felhantering C++)

void main(){ int result; try { result = dividera(5.0f, 0.0f); } catch (char * str) { // Division med noll!! }}

float dividiera(float taljare, float namnare){ if (taljare == 0) throw ”Division by zero”; return taljare/namnare;};

Page 15: Föreläsning  6

Exceptions

• Exceptions kan användas när det uppstår undantagsfel i programmet– Exempelvis om minnet tar slut, inläsning av

en trasig fil, avbruten kommunikation m.m.• Exceptions ger fördelen att

programmeraren kan förutsätta att allt går bra, men ifall det skulle uppstå problem så kan dessa hanteras

Page 16: Föreläsning  6

Exceptions

• Ett exception slängs med operatorn throw

• Valfritt objekt kan slängas– Klasshierarkier med olika Exception-objekt

kan med fördel användas• Objektet returneras bakåt i

anropshierarkin tills det fångas av en ”try – catch” rutin

Page 17: Föreläsning  6

Exceptions

• Exceptions kan ge en felhantering på hög nivå– Felet behöver inte tas omhand i den

felande funktionen eller i den direkt anropande funktionen

– Hantering av fel är inte alltid möjlig i den direkta närheten där felet uppstår, men kan med exceptions hanteras högre upp i anropshierarkin

Page 18: Föreläsning  6

Exceptions• Standardbiblioteket har en definierad

klasshierarki av exception-objekt

invalid_argument

out_of_range length_error

domain_error

exception

logic_error runtime_error

range_error

overflow_error underflow_error

bad_alloc bad_cast

Page 19: Föreläsning  6

Flera catch-uttryckvoid main(){ try { File file(”c:\kalle.txt”); string str = file.ReadString(); } catch (OutOfMemoryException e) { // Slut på minne vid inläsning } catch (BadFileFormatException e) { // Felaktigt filformat } catch (Exception e) { // Andra standardfel som kan uppstå } catch (...) { // Fånga ALLA andra fel här (DivisionByZero m.fl.) }}

Page 20: Föreläsning  6

Flera catch-uttryck

• Ett try-catch block kan ha flera catch-uttryck för att hantera flera olika fel

• Endast ett catch-uttryck exekveras– Det första som matchar

• Ellipsis (…) fångar alla fel– Om denna används bör den vara sist av

catch-uttrycken

Page 21: Föreläsning  6

Släng undantagsfel

• Syntax:– throw 4;– throw Klass();– throw Klass(konstruktorparametrar);

• Flera olika undantagsfel (objekt) kan slängas från en metod, men endast en i taget

Page 22: Föreläsning  6

Skicka vidare exceptions

• En metod kan behöva fånga undantagsfel utan att kunna hantera felet– Exempelvis kan en metod avallokera

minne för att undvika minnesläckage. För att sedan vidare hantering av felet skall ske så kan metoden skicka vidare felet med ”throw;” i catch-uttrycket

Page 23: Föreläsning  6

Skicka vidare …

void function(){ try { File file(”c:\kalle.txt”); string str = file.ReadString(); } catch (...) { cout << ”Fel uppstod vid läsning” << endl; throw; // Skicka vidare }}

Page 24: Föreläsning  6

Vad händer vid exceptions?• Stack unwind – anropsstacken plockas ned• Objekt på varje nivå destrueras• Minnesläckagerisk

– Om man allokerat minne måste detta avallokeras. Lämpligen genom att fånga felet, avallokera minnet samt skicka exception-objektet vidare.

Page 25: Föreläsning  6

Händelsestyrd programmering

• Programmet är passivt– Programmet ligger inaktivt så länge

ingenting händer• Lämpliga metoder anropas automatiskt

när vissa kriterier är uppfyllda– Musrörelser, Knapptryckningar m.m.

Page 26: Föreläsning  6

Fördelar

• Programmet slipper ”pollande” loopar, dvs loopar som hela tiden ligger och kollar om någonting skall göras.– Mindre processoråtgång– Viktigt i multiprocessystem (windows)

• Programmet kan koncentrera sig på att utföra uppgifter istället för att undersöka vad som skall göras

Page 27: Föreläsning  6

MFC

• Microsoft Foundation Classes• Klasspaket (framework)• Klasser för att programmera windows-

program• Bygger på Win32 API (application

programming interface)• Händelsestyrt

Page 28: Föreläsning  6

CCmdTarget

Viktiga MFC-KlasserCObject

CWnd

CFrameWnd

CView

CWinThread

CWinApp

CDocument

CDC

Basklass som alla MFC-klasser ärver från

Sköter hantering av meddelanden inom/mellan objekt

Basklass som hanterar alla grafiska ytor

Alla fönster ärver från denna

Hanterar utritning av innehållet i CFrameWnd

Trådhantering (multithreading)

MFC-applikationer börjar i denna klass

Motsvarande Modellen i Model-View-Controller

Används vid all utritning till CWnd-objekt

Page 29: Föreläsning  6

Nyttiga MFC-Klasser

CPoint

CSize

CRect

CString

CTime

Point-klass, liknande de som skapats i laborationerna

Hanterar storlekar (kompletterar CPoint)

Beskriver rektanglar och dess operationer

Stränghantering, liknande std::string

Operationer för tidsberäkningar

Page 30: Föreläsning  6

MFC-Wizard

• I Visual C++ får man följande upplägg av MFC Wizard (projekttyp)– Klass härledd från CWinApp

• Startar och initierar windows-programmet– Klass härledd från CFrameWnd

• Sköter allt specifikt för applikationsfönstret– Klass härledd från CView

• Sköter all utritning av data från CDocument– Klass härledd från Cdocument

• Hanterar all applikationsdata

Page 31: Föreläsning  6

Projektskelett (Bounce)

CBounceApp

CMainFrame

CBounceView

CBounceDoc

Skapar

InnehållerKänner till