*:85/ID200V C++ HT07. Föreläsning 8 Medlemspekare Undantagshantering Namnrymder



Relevanta dokument
Kapitel 6 - Undantag

TDIU20 - Objektorienterad programmering i c++ - föreläsning 4

C++ Objektorientering - Klasser. Eric Elfving Institutionen för datavetenskap

Det finns många flaggor till g++,

Kapitel 3. Synlighet. Kapitel 3 - Klassanvändning, operatorer och pekare. Synlighet

TDDC76 - Programmering och Datastrukturer

C++ Objektorientering - Klasser. Eric Elfving

Innehåll. Resource handles. Resurshantering. Minnesallokering. Minnesallokering Exempel: allokering på stacken. 7. Resurshantering, Felhantering

Synlighet. Namespace Scope-operatorn Klasser Vänner

TDIU01 Programmering i C++

Operatorer för medlemspekare

Innehåll. Pekare Exempel

Innehåll. Pekare Exempel

Programmering i C++ EDA623 Arv. EDA623 (Föreläsning 6) HT / 42

TDIU01 - Programmering i C++, grundkurs

Innehåll. Introduktion till objektorientering. OOP (objektorienterad programmering) Objekt, instanser, klasser

Programmering i C++ EDA623 Objektorienterad programutveckling. EDA623 (Föreläsning 5) HT / 33

Innehåll. Resurshantering. Resource handles. Minnesallokering. Minnesallokering Exempel: allokering på stacken. 6. Resurshantering

Del3 Klassanvändning, operatorer och pekare Ämnesområden denna föreläsning:

grundläggande C++, funktioner m.m.

Övriga byggstenar. Övriga byggstenar. Några tips under programutveckling. Beroenden Pekare till funktioner Typkonvertering

Introduktion till arv

Operatoröverlagring. endast operatorsymboler definierade i C++ kan överlagras = += -= *= /= %= ^= &= = <<= >>= < > <= >= ==!= && > ->*, [ ] ( )

Programsystemkonstruktion med C++: Övning 1. Karl Palmskog september 2010

TDIU01 - Programmering i C++, grundkurs

Tommy Färnqvist, IDA, Linköpings universitet

TDIU01 - Programmering i C++, grundkurs

Programsystemkonstruktion med C++

Ett enkelt program i C++, hello.cpp. #include <iostream> int main() { std::cout << "Hello World\n"; return 0; } C++, Övning 1

Programsystemkonstruktion med C++: Övning 2. Karl Palmskog september 2010

Innehåll. Exceptionella händelser (exceptions, undantag ) Felhantering Tre nivåer av felhantering: Nivå 2: exceptions (eller returvärde)

LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

C++-programmets beståndsdelar

Byggstenar. C++-programmets beståndsdelar. C++-programmets beståndsdelar. Grundläggande datatyper

DD2387 Programsystemkonstruktion med C++ Tentamen 1 Torsdag 7 januari 2016, 14:00-18:00

Programsystem konstruktion med C++ (2D1387) Innehåll. övning 2 klasser och arv

Dynamisk bindning och polymorfism

TDDC76 - Programmering och Datastrukturer

TDDC76 Programmering och datastrukturer

Innehåll. 1 Deklarationer, scope och livstid. 2 Användardefinierade typer. 4 In- och utmatning. 5 Operatoröverlagring. 6 namnrymder (namespace)

Funktionspekare, inledning: funktionsanropsmekanismen. Anrop via pekare

Del2 Klasser, medlemmar och arv Ämnesområden denna föreläsning:

TDDC76 - Programmering och Datastrukturer

Poster ( structar ) Postdeklarationer

Tentamen i Objektorienterad Programmering 5p, Au, D, Fri, Pr,

Tentamen i TDP004 Objektorienterad Programmering Lösningsförslag

SP:PROG3 HT12 Tenta

1 Klasser och objektorientering Vad är objektorientering?

TDDC76 - Programmering och Datastrukturer

Objektorientering - Arv och polymorfi. Eric Elfving Institutionen för datavetenskap

TDP004. Minne och pekare. Eric Elfving Institutionen för datavetenskap

Innehåll. 1 Deklarationer, scope och livstid. 2 Användardefinierade typer. 4 Operatoröverlagring. 5 In- och utmatning. 6 namnrymder (namespace)

1 Namnkontroll (NameControl)

Objektorienterad programmering

Pekare och arrayer. Indexering och avreferering

Nedan skapar vi klassen Person innehållande datamedlemmar för förnamn, efternamn, ålder, längd och vikt:

TDIU20 - Objektorienterad programmering i c++ - föreläsning 6

Att deklarera och att använda variabler. Föreläsning 10. Synlighetsregler (2) Synlighetsregler (1)

TDDC76 - Programmering och Datastrukturer

OOP Objekt-orienterad programmering

Introduktion. Klasser. TDP004 Objektorienterad Programmering Fö 2 Objektorientering grunder

5 Arv och dynamisk bindning FIGUR

UML. Klassdiagr. Abstraktion. Relationer. Överskugg. Överlagr. Aktivitetsdiagram Typomv. Typomv. Klassdiagr. Abstraktion. Relationer.

Innehåll. Pekaren this Självreferens. Klasser Resurshantering, representation. Överlagring av operatorer. Överlagring av operatorer

TDIU20 - Objektorienterad programmering i c++ - föreläsning 3

Tentamen *:58/ID100V Programmering i C Exempel 3

Funktionens deklaration

2D1387, Programsystemkonstruktion med C++ Johnny Bigert, Kursens hemsida:

Kapitel 1. C++-programmets beståndsdelar. C++-programmets beståndsdelar. Kapitel 1 grunderna i C++

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Outline. Objektorienterad Programmering (TDDC77) Att instansiera en klass. Objekt. Instansiering. Åtkomst. Abstrakt datatyp.

Föreläsning 4 Tillägg till C-syntaxen

Klasser. Kapitel 2. Kapitel 2 - Klasser, medlemmar och arv. Klasser. Klasser Medlemmar Arv

Det objektorienterade synsättet. Objekt. Datorprogrammet kan uppfattas som en slags modell av den verklighet programmet skall samverka med.

C++ Funktioner 1. int summa( int a, int b) //funktionshuvud { return a+b; //funktionskropp } Värmdö Gymnasium Programmering B ++ Datainstitutionen

allokeras på stacken dynamiskt new delete

OOP Objekt-orienterad programmering

Minneshantering. Minneshantering. Minneshantering. Undvik pekare

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

int (*fp) (char, char*) //pekare till funktion som tar //argumenten (char, char*) och //returnerar int

Minnestilldelning (allokering) och frigörande (avallokering) av minne

KLASSER. Inkapsling Abstrakt datatyp Public och private. Klassmedlemmar Datamedlemmar Exempel Funktionsmedlemmar

Användning av typeid. Operatorerna typeid och. Filen typeinfo.h måste inkluderas. typeid

Lektionsuppgifter. TDDI14 Objektorienterad programmering. Lektionsplanering Lektion Lektion Lektion

1 Funktioner och procedurell abstraktion

Trädtraversering. Binärt träd. Trädtraversering djupet-först. Trädtraversering bredden-först

Exempel. Arrayer. Lösningen. Ett problem. Arrayer och hakparanteser. Arrayer

Grundläggande C-programmering del 2 Pekare och Arrayer. Ulf Assarsson

Programmering i C++ EDA623 Mer om klasser. EDA623 (Föreläsning 6) HT / 26

Arrayer. results

Objektorienterad programmering i Java Undantag Sven-Olof Nyström Uppsala Universitet Skansholm: Kapitel 11

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

Föreläsning 6: Metoder och fält (arrays)

Objektorienterad programmering i Java Undantag Sven-Olof Nyström Uppsala Universitet Skansholm: Kapitel 11

Kapitel 5. Strömmar. Utmatning

Arv: Fordonsexempel. Arv. Arv: fordonsexempel (forts) Arv: Ett exempel. En klassdefinition class A extends B {... }

Arv. Fundamental objekt-orienterad teknik. arv i Java modifieraren protected Lägga till och modifiera metoder med hjälp av arv Klass hierarkier

Programmera i C Varför programmera i C när det finns språk som Simula och Pascal??

Innehåll. 1 Kort om dynamisk polymorfism. 2 Arv i C++ 3 Multipelt arv. 4 Något om statisk polymorfism. class Container {

Transkript:

*: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 (pointer to member) för sådana situationer (har ingen motsvarighet i Java). En medlemspekare är implementerad som ett offset in i ett objekt till den aktuella medlemmen (hur långt från objektets början medlemmen ligger). För att ge en viss medlem i ett visst objekt måste den kompletteras med ett objekt (namn eller referens) eller en pekare till ett objekt. Medlemspekare till medlemsfunktioner är mest användbara, men först lite synatx. Exempel: antag deklarationerna struct Strukt{ int x, y; ; Strukt vek[10]={{2,3, {5, 17, {3, 8,...; Antag att vi vill kunna summera ibland alla x i vek, ibland alla y: int Strukt::*mpek; // Deklaration av medlemspekare till en int i Strukt if (summera x) mpek=&strukt::x; // Medlemsadress -tagning else mpek=&strukt::y; int sum=0; for(int i=0; i<10; i++) sum += vek[i].*mpek; // Åtkomst via medlemspekaren Bild 106 1

Operatorer för medlemspekare C++ inför tre nya operatorer för medlemspekare och en notation för medlemsadress -tagning: ::* - deklarator för medlemspekare, t.ex. int Strukt::*mpek; Obs alltså att medlemmarnas typ och klassens namn ingår. Medlemsadress - tagning - Adressen till en medlem fås genom notationen mpek=&strukt::x; Obs dock att det är en specialkonstruktion, i själva verket står en medlemspekare för ett offset, inte för en adress. Detta offset måste kombineras med en pekare till ett objekt eller med ett objekt (eller en referens till ett objekt) ->* - åtkomst till en medlem via medlemspekare hos ett objekt som pekas ut av en objektpekare, t.ex. int i=pek->*mpek;.* - åtkomst till en medlem via medlemspekare hos ett objekt (eller en objektreferens), t.ex.: Strukt obj={5, 7; int i=obj.*mpeki; Bild 107 Pekare till medlemsfunktioner Exempel: class Valued{ int value; public: Valued():value(0){ void add(int v){value+=v; void sub(int v){value-=v; void mult(int v) {value*=v; ; Valued values[10]; void (Valued::*mfunk)(int i); //Pekare till medlemsfunktion cout << Operation värde: char perator; int perand; cin >> perator >> perand; switch(perator){ case + : mfunk=&valued::add; break; case - : mfunk=&valued::sub; break; case * : mfunk=&valued::mult; break; for(valued *pek=values; pek<values+10; pek++) (pek->*mfunk)(perand); Bild 108 2

Mer om medlemsfunktionspekare Medlemsfunktionspekare kan t.ex. läggas i datastrukturer som objekt, map<>, arrayer: void (Valued::*mfarr[3])(int) = {&Valued::add, &Valued::sub, &Valued::mult; Varvid både objektet och operationen kan indexeras: (values[5].*mfarr[1])(3); // Anropar values[f].sub(3); Definitionen av arrayen kan förenklas med typedef: typedef void (Valued::*Valfunk)(int); Valfunk mfarr[3]={&valued::add, &Valued::sub, &Valued::mult; Oftast görs sådana typnamndefinitionen i klassen varvid klassnamnet syns i arraydefinitionen: class Valued{ public: typedef void (Valued::*Mfunk)(int);... ; Valued::Mfunk mfarr[3]={&valued::add,&valued::sub,&valued::mult; Bild 109 Användning av medlemsfunktionspekare Den viktigaste användningen av medlemsfunktionspekare är för sammankoppling av bibliotekskomponenter med medlemsfunktioner i en tillämpnings objekt. Jämför med Javas grafiska komponenter: man installerar s.k. lyssnare som måste ha metoder med föreskriven signatur (namn och argumenttyper), t.ex. void actionperformed(actionevent); Om tillämpningens objekt behöver reagera olika på olika händelser av denna typ och behöver ha flera sådana metoder tvingas man införa nya klasser (oftast inre klasser; s.k. lyssnarklasser) eftersom en klass inte kan ha flera metoder med samma signatur. I C++ med användning av medlemsfunktionspekare kan man skapa direkta kopplingar mellan bibliotekskomponenter och olika medlemsfunktioner i objekt av en tillämpningsklass, dessa medlemsfunktioner behöver inte ha något föreskrivet namn. Eftersom deklarationen av en medlemspekare måste innehålla namnet på tillämpningens klass där medlemsfunktionen ingår måste en sådan koppling i ett bibliotek göras som en mall. Vi återkommer till hur detta görs. Bild 110 3

Orientering om undantagshantering Undantagshantering i C++ liknar mycket Javas, som lånat mekanismen och syntaxen från C++. Den är dock inte lika genomgripande som i Java - bl.a. kunde man inte införa run-time-kontroller p.g.a. kravet på kompatibilitet med C. Undantag genereras av biblioteket och run-time-systemet endast i ett fåtal fall, indexering utanför arraygränser eller avreferering av null-pekare ger inga undantag utan eventuellt ett vanligt exekveringsavbrott ( Segmentation fault ). Viktigaste skillnader mot Java: egna undantagsklasser används (dock finns en liten bibliotekshierarki) vid throw används inte new, man skapar temporära objekt vid catch behöver inte argumentet namnges argumenttypen till catch bör deklareras som referens att fånga alla undantag görs med catch(...) det finns ingen motsvarighet till finally undantagsspecifikationer är inte obligatoriska i en undantagshanterare kan throw skrivas utan argument, innebär att samma undantag skickas vidare (re-throw) Bild 111 Standardbibliotekets undantagshieraki Felaktiga argumentvärden m.m., programmeringsfel logic_error exception Andra fel som upptäcks under exekveringen runtime_error length_error out_of_range bad_alloc bad_exception domain_error invalid_argument bad_cast ios_base::failure range_error overflow_error underflow_error Klasserna exception och bad_exception finns i headerfilen <exception>, de flesta andra i <stdexcept>, men ios_base::failure i <ios> Bild 112 4

Standardbibliotekets undantagshieraki, forts. I klassen exception deklareras virtual const char *what() const; som subklasserna är tänkta att överskugga för att returnera en C-sträng med ett meddelande som kan skrivas ut. Konstruktorerna i logic_error och runtime_error kräver en sträng (std::string) med ett meddelande som kommer att lagras i undantagsobjektet för att returneras vid efterföljande what()-anrop. length_error en längdangivelse skulle överskrida max domain_error värde av fel matematisk domän out_of_range värde utanför tillåtet intervall (t.ex. vid indexering) invalid_argument otillåtet funktionsargument bad_alloc inget minne vid dynamisk allokering bad_exception odeklarerat undantag från en funktion (se nästa bild) bad_cast misslyckad dynamic_cast för referens ios_base::failure misslyckad iostream-operation (måste begäras) range_error intervallfel i interna beräkningar overflow_error aritmetiskt overflow underflow_error aritmetiskt underflow Bild 113 Undantag: syntaktiskt exempel #include <stdexcept> class Text{ int size; char *cptr; public:... char& operator[](int index){ if (index < 0 index >= size) throw std::out_of_range( Text index error ); return cptr[index];... ; #include Text.h #include <iostream> using namespace std; int main(){ Text t( Eberhart von Ostenbrink ); try{ cout << Vilken position: ; int pos; cin >> pos; cout << t[pos]; catch(out_of_range& oor){ cerr << Fel: << oor.what() << endl; Bild 114 5

Ofångna undantag Om ett ofånget undantag når main() (och inte fångas upp där heller) anropas funktionen std::terminate() som avbryter programmet genom att anropa abort() Man kan sätta en egen termineringsfunktion (argumentlös funktion med void som returtyp, (void (*)())) med std::set_terminate(void (*handler)()). En termineringsfunktion förväntas avbryta programmet (annars anropas abort() ändå). Bild 115 Undantagsspecifikationer En funktion eller konstruktor kan deklarera att den kan generera vissa undantag: void funk(string str,int i) throw(bad_alloc, range_error); Undantagsspecifikationer är en del av funktionens signatur och måste upprepas i definitionen (om man har både en deklaration och en definition). Eftersom undantagsspecifikationer lades till C++ när språket redan användes kunde man inte göra undantagsspecifikationer obligatoriska. Istället är det så att en funktion utan undantagsspecifikation kan generera alla undantag. För att deklarera att en funktion inte tänks generera några undantag skriver man: void funk(string str, int i) throw(); Om en funktion med en undantagsspecifikation genererar ett odeklarerat undantag sker ett anrop till std::unexpected() som i sin tur anropar std::terminate(). Om funktionen innehåller bad_exception i sin undantagsspecifikation genereras istället detta undantag. Dessutom kan man sätta en egen funktion (void (*)()) som unexpected genom anrop till std::set_unexpected(void (*handler)()). Bild 116 6

Undantagshierarkier Liksom i Java brukar man samla undantag som hör ihop i en klasshierarki: #include <stdexcept> struct Stack_error:public std::length_error{ Stack_error(const std::string& msg):std::length_error(msg){ ; struct Stack_full:public Stack_error{ Stack_full(const std::string& msg):stack_error(msg){ ; struct Stack_empty:public Stack_error{ Stack_empty(const std::string& msg):stack_error(msg){ ; class Stack{ int data[100]; int count; public: Stack():count(0){ void push(int value) throw(stack_full){ if (count == 100) throw Stack_full("Stack full"); data[count++]=value; int pop() throw(stack_empty){ if (count == 0) throw Stack_empty("Stack empty"); return data[--count]; Bild 117 ; Undantagshierarkier Vad man uppnår genom att gruppera undantagen är att tillämpningar kan fånga undantagen med basklassnamnet (om de inte är intresserade av vilket specifikt undantag som genererades). Motsvarande gäller undantagsspecifikationer. Liksom i Java undersöks catch-fraserna uppifrån och ner, vill man ha en speciell hantering av ett visst undantag och mer generell hantering av övriga undantag så måste de specifika undantagstyperna stå först: Stack stack; try{ for(int i=0; i<x; i++) stack.push(i); for(int i=0; i<y; i++) cout << stack.pop(); catch(stack_full&){ // Specifikt Stack_full-undantag cerr << För många tal! << endl; catch(stack_error&){ // Andra Stack-undantag cerr << Fel vid stackhantering! << endl; catch(length_error&){ // Andra length_error-undantag cerr << För mycket eller för lite av något! << endl; catch(...){ // Alla andra undantag cerr << Ett fel har inträffat! << endl; Bild 118 7

Resurshantering vid risk för undantag m.m. Viktigt att komma ihåg är att det inte finns någon automatisk garbage collection i C++. Detta gör att om en funktion allokerar minne dynamiskt i början med avsikt att friställa minnet i slutet, men kan däremellan avbrytas av undantag så sker ett minnesläckage. Även i andra sammanhang (öppna / stänga filer o.s.v.) kan det hända att en avslutningsoperation inte utförs vid undantag. Ett bra sätt att undvika detta är att resursanskaffning sker i konstruktorn till ett lokalt objekt och återlämnande sker i objektets destruktor. Vid eventuellt undantag städas objektet bort, dess destruktor anropas och kan städa efter anropet. Speciellt för minnesallokering kan standardbibliotekets auto_ptr<> från headerfilen <memory> användas istället för pekare: void funk() throw(bad_alloc, range_error) {. auto_ptr<person> pers(new Person( Ulrika ));... Bild 119 Undantag och konstruktorer/destruktorer En konstruktor som upptäcker sådana fel i sina argumentvärden att den inte kan konstruera ett meningsfullt objekt kan inte göra annat än generera ett undantag: // Rational.h #include <stdexcept> class Rational{ int num, den; public: explicit Rational(int n=0, int den=1) throw(std::invalid_argument);... // Rational.cpp #include Rational.h using namespace std; Rational::Rational(int n, int d) throw(invalid_argument):num(n), den(d){ if (d == 0) throw invalid_argument( Rational: zero denominator! ); reduce(num, den); En destruktor å andra sidan får inte generera undantag det kan hända att den är anropad under uppstädning av stacken pga ett annat undantag. Om detta inträffar anropas terminate()-funktionen. Bild 120 8

Deklarationsvidder Namn i ett program är deklarerade i olika deklarationsvidder (scope). En deklarationsvidd är ett textuellt område i programmet där namnet är känt av kompilatorn och bundet till det det är namn på (en variabel, en funktion, en typ...). Obs att deklarationsvidder är en statisk, textuell gruppering av namn som bara har betydelse i källkoden och inte överlever kompilering. I C++ finns följande typer av deklarationsvidder: den globala vidden namnrymder klasser funktioner block Bild 121 Deklarationsviddsoperatorn :: Om man från utanför en deklarationsvidd vill referera till ett namn deklarerat inom en deklarationsvidd använder man viddens namn följt av deklarationsviddsoperatorn :: och det namn man vill använda (gäller inte funktioner och block, namn deklarerade i dessa vidder existerar inte utanför vidderna): std::cout << Hej hopp! << std::endl; Obs att viddens namn och :: skrivs närmast namnet, även om de ingår i ett mer sammansatt uttryck: pek->person::get_name(); Om man i en deklarationsvidd vill använda ett namn från den globala vidden som gömts av ett lokalt deklarerat namn kan man använda :: utan namn på vidden: int x=13; void funk(){ int x=173; cout << ::x; // Det globala x, 13 skrivs ut En deklarationsviddsoperator finns även i Java, men den ser ut på samma sätt som medlemsåtkomstoperatorn (alltså en punkt). Bild 122 9

Namnrymder Namnrymder utgör ett enkelt sätt att gruppera namn på typer (t.ex. klasser), funktioner o.s.v. som hör ihop inom ett namn: #ifndef TEXT_H #define TEXT_H #include <iostream> namespace mylib{ class Text{ public: Text(const char *str); int length() const; // o.s.v. ; // end of class Text std::ostream& operator<<(std::ostream&, const Text&); // end of namespace mylib #endif På det sättet uppnår man en naturlig gruppering av namn som hör ihop och undviker olösbara namnkonflikter i tillämpningar som kanske använder andra bibliotek som också deklarerar namnet Text (med en annan betydelse) Namnrymder motsvaras närmast av package i Java, men har i C++ ingen betydelse för medlemmarnas åtkomstskydd. Det finns inte heller några krav på header-/källkodsfiler, kataloger o.s.v. Bild 123 Namnrymder, forts 1. Vid definition av ett namn som deklarerats inom en namnrymd kan varje namn kvalificeras med namnrymdens namn för sig: #include Text.h #include <cstring> mylib::text::text(const char *str): size(std::strlen(str)+1), cptr(new char[size]){ std::strcpy(cptr, str); int mylib::text::length() const { return size; Men namnrymder är öppna, man kan introducera definitionerna och även deklarera nya namn i samma namnrymd: #include Text.h #include <cstring> namespace mylib{ Text::Text(const char *str): size(std::strlen(str)+1), cptr(new char[size]){ std::strcpy(cptr, str); int Text::length() const { return size; Bild 124 10

Namnrymder, forts. 2 Namnrymder är som sagt öppna, man kan deklarera nya namn i samma namnrymd (på samma sätt som man i Java kan deklarera flera klasser som hörande till samma package): #ifndef KLOCKA_H #define KLOCKA_H #include <iostream> namspace mylib{ class Klocka{ // o.s.v. ; std::ostream& operator<<(std::ostream&, const Klocka&); #endif Namnrymder bör användas för grova grupperingar av namn. Vid utveckling av ett bibliotek bestående av många klasser och hjälpfunktioner borde hela biblioteket göras till en namnrymd eller ett fåtal namnrymder. Bild 125 Anonyma namnrymder För att göra vissa namn privata för en modul (källkodsfil) kan man använda anonyma namnrymder: namespace{ // hjälpfunktioner, privata för modulen void helper1(...) {... void helper2(...) {... void funk() { helper1(...); Inom källkodsfilen blir namnen från den anonyma namnrymden tillgängliga utan någon kvalifikation, utanför denna källkodsfil är de otillgängliga. Detta ersätter C:s deklarationer av globala namn som statiska för att gömma dem för andra moduler (mekanismen finns kvar, men bör inte användas). Bild 126 11

using-direktiv och using-deklarationer Med ett using-direktiv (using namespace...) som används med namnrymder öppnar man hela namnrymden, som om alla namn i namnrymden lades in i den globala namnrymden, t.ex. #include <iostream> #include <string> using namespace std; Med using-deklarationer hämtar man in ett visst namn från en annan deklarationsvidd till en lokal deklarationsvidd, t.ex. #include <iostream> #include <string> void funk(){ using std::string; using std::cout; string namn = Jozef ; cout << namn << std::endl; Bild 127 Namnrymder: namnuppslagning, alias Begrunda följande kod: #include <iostream> #include <string> //Inget using namespace std-direktiv int main(){ std::string namn( Jozef ); std::cout << namn; // Var finns operator<<(ostream&, string)? Om kompilatorn inte hittar den anropade funktionen i den lokala namnrymden letar den efter funktionen i de namnrymder där argumenttyperna är definierade (Koenig lookup). För att man inte skall dra sig för att ge namnrymder meningsfulla, långa namn kan man skapa alias till namnrymder: namespace star85_library_at_dsv_ht06{... namespace s85= star85_library_at_dsv_ht06; Bild 128 12