Synlighet. Namespace Scope-operatorn Klasser Vänner

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

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

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

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

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

allokeras på stacken dynamiskt new delete

Minneshantering. Minneshantering. Minneshantering. Undvik pekare

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

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

TDDC76 - Programmering och Datastrukturer

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

Dynamisk bindning och polymorfism

Kapitel 6 - Undantag

Programsystemkonstruktion med C++

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

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

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

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

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

1 Namnkontroll (NameControl)

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

Innehåll. Typomvandlingar (casting) Implicita Typomvandlingar. Typomvandlingar (type casts) Explicita, namngivna typomvandlingar (C++-11)

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

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

Klasshierarkier - repetition

Innehåll. Användardefinierade typer. Användardefinierade typer Kategorier. Konstruktorer. Konstruktorer Två sätt att skriva initiering av medlemmar

TDDC76 Programmering och datastrukturer

TDDC76 - Programmering och Datastrukturer

Det finns många flaggor till g++,

Introduktion till arv

Tentamen i DD2387 Programsystemkonstruktion med C++

Innehåll. Konstruktorer vid arv Regler för basklassens konstruktor. Konstruktorer vid arv. Konstruktorer vid arv. Konstruktorer vid arv

Föreläsning 8. Arv. Arv (forts) Arv och abstrakta klasser

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

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

Tentamen i TDP004 Objektorienterad Programmering Lösningsförslag

Problemet. Vi har sett att vi kan ersätta de metoder vi ärver från överklassen med egen funktionalitet (polymorfism)

Polymorfi. Objektorienterad och komponentbaserad programmering

TENTAMEN CD5250. Objektorienterad programutveckling med C++, 5p. Datum: , Tid: 14:00-19:00

Kapitel 4 - Mallar. Kapitel 4. Introduktion till mallar STL. 2D1387 Programsystemkonstruktion med C++ 1

Kapitel 4. Funktionsmallar. Mallar. Introduktion till mallar STL

Tentamen EDAF30 Programmering i C++

Objektorienterad programmering Föreläsning 6. Mer om klasser och typer Namnrymder Inkapsling Synlighet Statiska variabler Statiska metoder

Innehåll. dynamisk bindning. och programmering CRC) u Arv, polymorfi och

TDIU01 Programmering i C++

Objekt-orienterad programmering. Klassbegreppet och C++ UML. UMLs fördelar

Arv. Objektorienterad och komponentbaserad programmering

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

2I1049 Föreläsning 5. Objektorientering. Objektorientering. Klasserna ordnas i en hierarki som motsvarar deras inbördes ordning

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

Konstruktion av klasser med klasser

Tentamen *:85/2I4123 C

Innehåll. Pekare Exempel

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

F8 - Arv. ID1004 Objektorienterad programmering Fredrik Kilander

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

Vad är en klass? Övning 2. Konstruktorer. ffl copy-konstruktorn tar en instans av klassen som. ffl default-konstruktorn tar inga argument och kan

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

5 Arv och dynamisk bindning FIGUR

Innehåll. Pekare Exempel

Föreläsning 5 (6) Metoder. Metoder Deklarera. Metoder. Parametrar Returvärden Överlagring Konstruktorer Statiska metoder tostring() metoden javadoc

Kapitel 4. Funktionsmallar. Mallar. Introduktion till mallar STL

Idag. Javas datatyper, arrayer, referenssemantik. Arv, polymorfi, typregler, typkonvertering. Tänker inte säga nåt om det som är likadant som i C.

TDIU01 - Programmering i C++, grundkurs

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

Lektionsuppgifter. TDDI14 Objektorienterad programmering. Lektionsplanering Lektion Lektion Lektion

F8: Typkonvertering i C++

Föreläsning 5-7 Operatoröverlagring

Innehåll. Typomvandlingar (casting) Implicita Typomvandlingar. Typomvandlingar (casting) Implicita Typomvandlingar

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

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

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

Föreläsning 4. Klass. Klassdeklaration. Klasser Och Objekt

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

Objektorienterade programmeringsspråk. Objektorienterade språk. Den objekt-orienterade modellen. Jämför med icke-oo

Kapitel 5. Strömmar. Utmatning

1 Klasser och objektorientering Vad är objektorientering?

C++-programmets beståndsdelar

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

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

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

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

DAT043 - Föreläsning 7

Exempelvis pekarvariabler blir då lättare korrekt deklarerade och initierade.

Skapa, kopiera och destruera klassobjekt

Tentamen i TDP004 Objektorienterad Programmering Lösningsförslag

Objektorienterad programmering

Föreläsningsmaterial (Arv) Skrivet av Andreas Lund

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

OOP Objekt-orienterad programmering

Objektorientering - Arv och polymorfi

Funktionspekare, inledning: funktionsanropsmekanismen. Anrop via pekare

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

1 Funktioner och procedurell abstraktion

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

TDIU01 - Programmering i C++, grundkurs

Klasshierarkier. Klasser kan byggas på redan definierade klasser

Föreläsning 8 - del 2: Objektorienterad programmering - avancerat

Objektorienterad Programmering (TDDC77)

Föreläsning 8 Programmeringsteknik och Matlab 2D1312/2D1305. Klass Object, instans av klass public/private Klassvariabler och klassmetoder

Transkript:

Synlighet Namespace Scope-operatorn Klasser Vänner

Synlighet Ett problem med moduler i C är att alla variabel- och funktionsnamn ligger globalt synliga. C++ botar detta genom att införa det mycket användbara nyckelordet namespace I namnrymder kan man kapsla in klasser, funktioner och data Med synlighetsoperatorn (scope operator) :: kan man komma åt en namnrymd och medlemmar i klasser

Synlighet Med using exponerar man innehåll i en namnrymd Med odöpta namnrymder (unnamed namespaces) kan man deklarera data som endast är synliga i filen där de är definierade ObsoIet metod: I C (och därför även C++) skapar man filstatiska funktioner genom nyckelordet static Genom att ha fillokala data minskar risken för namnkonflikter

Synlighet namespace Spc // håll namnen på namnrymder korta { class A; // framåt(forward)deklaration int foo(); int j; enum {arms = 2, legs = 1, hair = 517}; } class Spc::A // A är inte synlig utan Spc:: { public : int foo(); int j; }; inline int Spc::A::foo() {return j;} // använder Spc::A::j inline int Spc::foo() {return j;} // ok: Spc::j synlig

Synlighet int main() { if(spc::j > Spc::legs) // Använd Spc::j och { /*...*/ } // Spc::legs explicit using Spc::j; // j synlig i hela main() j = Spc::foo(); // foo() ej synlig, använd Spc:: Spc::A a; j = a.foo(); // Spc::A::foo() synlig genom a using Spc::A; // hela klassen A synlig using namespace Spc; // allt data i Spc synligt } return 0;

Några överkursexempel på namnrymder och using namespace XYZ_version1 { int i; void foo(); // deklaration } namespace XYZ_version2 { int i; int j; void foo(); // deklaration } namespace XYZ = XYZ_version2; // alias för namnrymd void XYZ::foo() {} // definition av XYZ_ver2::foo int i; // global variabel i int j; // global variabel j // exempel på usingdeklaration (enstaka variabel) { using XYZ::i; // lokal i, gömmer global i i = 3; // ok: lokal i } // exempel på usingdirektiv (hel namnrymd) { using namespace XYZ; // introducerar i, j och foo j = 4; // fel! ::j eller XYZ::j? }

Synlighet Man kan byta synlighet på medlemmar med using struct A { protected: int i; }; struct B : public A { using A::i; }; A a; B b; a.i = 1; // fel: i är protected b.i = 2; // ok

Synlighet och klasser För att komma åt data i klasser använder man synlighetsoperatorn :: Ett bra exempel på hur synlighetsoperatorn används är STLs iteratorer Iteratorerna är inkapslade i behållarklasserna och döpta till samma sak: T::iterator resp. T::const_iterator

Synlighet och klasser Nedanstående exempel visar hur man kan använda klassens synlighetoperator för att abstrahera sin kod // här kan vi byta till lämpligare behållare vid behov // t.ex. std::vector eller std::deque typedef std::list<std::string> T; T t;... // oavsett klass, hämta dess const_iterator T::const_iterator i = t.begin(); for(; i!= t.end(); ++i) std::cout << *i << std::endl;

const Deklarationer med const ger skrivskydd. class A { const int ci; // ci är skrivskyddad (ssk) const int *p_ci; // pekare till ssk int int *const cp_i; // ssk pekare till int const int *const cp_ci; // ssk pekare till ssk int int get() const; // objektet är ssk i get int i; }; // källkodsfil int A::get() const { return i; } // ok: ändrar inte int A::get() const { return i = 2; } // fel: ändrar obj

const och mutable Funktioner deklarerade med const gör objektet read-only. Med mutable inför man ett undantag. class A { int get() const; // objektet är read-only i get int i; mutable int access_count; }; inline int A::get() const { access_count++; // ok: får ändras trots const return i; }

Vänner Ibland måste en klass ha tillgång till data i en annan Man vill dock inte använda åtkomsttypen public eftersom man får oönskad insyn Man specificerar sina vänner (klass eller funktion) med friend De får då åtkomstnivå public på data och funktioner friend-förhållandet ärvs inte friend bör undvikas för att inte äventyra inkapslingen

Vänner class MyInt { int i; // i är private public: MyInt(int j) : i(j) {} friend const MyInt operator*(int, const MyInt &); friend std::ostream & operator<<(std::ostream &, const MyInt &); }; inline const MyInt operator*(int i, const MyInt &j) { return MyInt(i * j.i); } // kommer åt MyInt::i inline std::ostream & operator<<(std::ostream &s, const MyInt &j) { s << "{MyInt = " << j.i << "}"; } // kommer åt MyInt::i

Överlagring av operatorer Konstanta referenser Returtyper Argumenttyper

Överlagring av operatorer Man kan omdefiniera operatorerna i C++ Detta gäller dock endast för egna typer såsom klasser, enums etc.

Överlagring av operatorer Exempel på operatoröverlagring class MyInt { public: const MyInt &operator=(const MyInt &); // tilldeln. const MyInt &operator+=(const MyInt &); // tilldeln. const MyInt operator+(int) const; // addition const MyInt operator+(const MyInt &) const;... }; MyInt i, j; i = j + 7; // använd oper+() och oper=() j += i; // använd oper+=() i.operator+=(j); // operatorer kan användas explicit

Överlagring av operatorer Det är viktigt att tänka på returtyperna för operatorerna Ta addition som exempel: inget av de ingående objekten innehåller resultatet och därför måste en temporär skapas Tar man däremot prefix ++-operatorn så håller objektet själv rätt värde och kan returneras som referens Om returnerade referenser ska vara const är olika från fall till fall och beroende på klassens användningsområden (ta exempel heltalsklass): helst const i fallet (a = b) = c inte nödvändigtvis const om (rect = r).normalize() Är man osäker härmar man beteendet hos int

Överlagring av operatorer Ytterligare exempel på operatoröverlagring class B; class A { int operator()(int, double); // anropsoper B &operator[](int) const; // indexering B &operator[](const char *) const; // (i t.ex. map) const A operator++(int); // postfix inkr. const A &operator--(); // prefix dekr. const A operator*(const A &) const; // multiplikation A &operator*(); // avreferering }; const A operator*(int, const A &); // extern mult std::ostream &operator<<(std::ostream &, const A &);

Polymorfi Dynamisk bindning Virtuella funktioner Virtuella destruktorer Strikt virtuella funktioner Abstrakta basklasser

Virtuella funktioner Normalt sett: kompilatorn vet vilken funktion som skall köras vid funktionsanrop - statisk bindning Virtuella funktioner: vilken funktion som körs bestäms av vilket objekt funktionen anropats genom - dynamisk bindning. Detta kallas polymorfi beteendet bestäms vid körningstillfället Polymorfi är endast applicerbart på pekare och referenser eftersom typen på ett objekt är känt vid kompileringstillfället.

Virtuella funktioner struct A { void print() { std::cout << "A"; } virtual void vprint() { std::cout << "A"; } }; struct B : public A { void print() { std::cout << "B"; } virtual void vprint() { std::cout << "B"; } }; A a; B b; A *ap = &b; // ok: B är subklass till A A &ar = b; // ok: ar refererar a ap->vprint(); // polymorfi: skriver ut "B" ar.vprint(); // polymorfi: skriver ut "B" ap->print(); // ej polymorfi: skriver ut "A" ar.print(); // ej polymorfi: skriver ut "A" b.vprint(); // objekt: skriver ut "B" B *bp = &a; // fel: A är inte nedärvd från B

Virtuella destruktorer För att alla objekt i en arvskedja skall få sina destruktorer anropade krävs att basklassen har en virtuell destruktor. class Av { public: virtual ~Av(); }; class Bv : public Av { public: ~Bv(); }; class A { public: ~A(); }; class B : public A { public: ~B(); }; B *bp = new B; A *ap = bp; delete ap; // fel?: B's destruktor anropas inte Bv *bvp = new Bv; Av *avp = bvp; delete avp; // ok: B's destruktor anropas

Abstrakta basklasser och strikt virtuella funktioner En strikt virtuell (pure virtual) funktion tvingar subklasser att ge en definition Basklassen kan då inte instantieras och kallas därför abstrakt basklass En abstrakt basklass definierar ett interface som alla nedärvda klasser måste följa

Abstrakta basklasser och strikt virtuella funktioner class A { public: virtual void print() = 0; // strikt pga '=0' }; class B : public A { public: void print(); // definition måste ges om }; // B skall instantieras void B::print() { std::cout << "B" << std::endl; }... A a; // fel: A är en abstrakt basklass B b; // ok: B har alla funktioner definierade b.print(); // kör B::print();