1 / 31

Föreläsning 6

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…) { ... }.

tuyet
Download Presentation

Föreläsning 6

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Föreläsning 6

  2. 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…){ ... }

  3. Templates i templates • ”Templatiserade” klasser kan ta templates som argument • std::vector<Point<float> > vektor; • Observera; mellanslag mellan de avslutande hakarna!

  4. 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…); ... };}

  5. 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)

  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;elseif (typeid(*fp) == typeid(Buss)) cout << ”fp är en buss” << endl;elseif (typeid(*fp) == typeid(Lastbil)) cout << ”fp är en personbil” << endl;};

  7. Upcast • Vi har tidigare sett att man kan behandla specialiserade klasser på samma sätt som mindre specialiserade klasser void 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!};

  8. 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

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

  10. 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”;}

  11. 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

  12. 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;};

  13. 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;};

  14. 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;};

  15. 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

  16. 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

  17. 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

  18. Exceptions • Standardbiblioteket har en definierad klasshierarki av exception-objekt exception logic_error runtime_error bad_alloc bad_cast out_of_range length_error range_error invalid_argument domain_error overflow_error underflow_error

  19. Flera catch-uttryck void 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.)}}

  20. 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

  21. 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

  22. 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

  23. 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}}

  24. 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.

  25. 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.

  26. 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

  27. MFC • Microsoft Foundation Classes • Klasspaket (framework) • Klasser för att programmera windows-program • Bygger på Win32 API (application programming interface) • Händelsestyrt

  28. Viktiga MFC-Klasser CObject Basklass som alla MFC-klasser ärver från CCmdTarget Sköter hantering av meddelanden inom/mellan objekt CWnd Basklass som hanterar alla grafiska ytor Alla fönster ärver från denna CFrameWnd Hanterar utritning av innehållet i CFrameWnd CView CWinThread Trådhantering (multithreading) MFC-applikationer börjar i denna klass CWinApp CDocument Motsvarande Modellen i Model-View-Controller CDC Används vid all utritning till CWnd-objekt

  29. Nyttiga MFC-Klasser CPoint Point-klass, liknande de som skapats i laborationerna CSize Hanterar storlekar (kompletterar CPoint) CRect Beskriver rektanglar och dess operationer CString Stränghantering, liknande std::string CTime Operationer för tidsberäkningar

  30. 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

  31. Projektskelett (Bounce) CBounceApp Skapar CMainFrame CBounceDoc Innehåller Känner till CBounceView

More Related