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
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…){ ... }
Templates i templates
• ”Templatiserade” klasser kan ta templates som argument– std::vector<Point<float> > vektor;– Observera; mellanslag mellan de
avslutande hakarna!
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…); ... };}
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)
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;};
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!};
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
typecast
void main(){ Horse horse; Car * car1 = &horse; // kompilatorn varnar Car * car2 = (Car*)&horse; // accepteras car2->ShiftGear(3); // PROGRAMKRASCH!}
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”;}
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
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;};
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;};
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;};
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
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
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
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
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.) }}
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
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
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
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 }}
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.
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.
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
MFC
• Microsoft Foundation Classes• Klasspaket (framework)• Klasser för att programmera windows-
program• Bygger på Win32 API (application
programming interface)• Händelsestyrt
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
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
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
Projektskelett (Bounce)
CBounceApp
CMainFrame
CBounceView
CBounceDoc
Skapar
InnehållerKänner till