TDIU01 Programmering i C++

Relevanta dokument
TDDC76 - Programmering och Datastrukturer

TDIU01 - Programmering i C++, grundkurs

TDIU01 - Programmering i C++, grundkurs

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

C++ Objektorientering - Klasser. Eric Elfving

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

TDDC76 - Programmering och Datastrukturer

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

Tillämpad programmering

TDIU01 - Programmering i C++, grundkurs

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

Skapa, kopiera och destruera klassobjekt

1 Klasser och objektorientering Vad är objektorientering?

TDDC76 - Programmering och Datastrukturer

TDDC76 - Programmering och Datastrukturer

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

TDIU01 (725G67) - Programmering i C++, grundkurs

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

Tommy Färnqvist, IDA, Linköpings universitet

TDDC76 - Programmering och Datastrukturer

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

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

5 Arv och dynamisk bindning FIGUR

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

Övningar Dag 2 En första klass

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

Lektionsuppgifter. TDDI14 Objektorienterad programmering. Lektionsplanering Lektion Lektion Lektion

TDIU01 - Programmering i C++, grundkurs

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

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

C++ - En introduktion

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

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

Introduktion till arv

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

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

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

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

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

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

Programsystemkonstruktion med C++

1. Klass med en dynamiskt allokerad variabel, definitionsfilen-del Klass med en dynamiskt allokerad variabel, inkluderingsfilen.

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

DD2387 Programsystemkonstruktion med C++ Tentamen 2

TDDC76 - Programmering och Datastrukturer

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

Programmering i C++ EDAF30 Dynamiska datastrukturer. EDAF30 (Föreläsning 11) HT / 34

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

Innehåll. 1 Typdeklarationer och typomvandling 2 Resurshantering. 3 Objektorientering, kort repetition. 4 Klasser

maxlist-1. Indexerad lista Länkad lista

TDIU01 - Programmering i C++, grundkurs

Klasser. Det är egentligen nu som kursen i programmeringsteknik börjar..., s k objektorienterad programmering.

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

Innehåll. 1 Funktionsmalllar. 2 Klassmallar. struct Name { string s; //... }; const Name & minimum ( const Name & a, const Name & b) { if(a.s < b.

TDDC76 Programmering och datastrukturer

Programmering i C++ EDA623 Dynamiska datastrukturer. EDA623 (Föreläsning 11) HT / 31

C++ - En introduktion

BINÄRA TRÄD. (X = pekarvärdet NULL): struct int_bt_node *pivot, *ny; X X X 12 X X 12 X X -3 X X

Föreläsning 5. Träd Binära träd Binärt sökträd som ADT Implementering av binärt sökträd Travestera binärt sökträd Sökning Insättning/borttagning

Funktionens deklaration

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

LÖSNINGSFÖRSLAG TILL Tentamen i objektorienterad programmering i C++ I

Innehåll. Pekare Exempel

Bankkonto - övning. Övning 2 Skriv en metod, geträntan, som returnerar räntan.

Föreläsning 5-6 Innehåll. Exempel på program med objekt. Exempel: kvadratobjekt. Objekt. Skapa och använda objekt Skriva egna klasser

Introduktion till Datalogi DD1339. Föreläsning 2 22 sept 2014

Innehåll. Pekare Exempel

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

Föreläsning 5-6 Innehåll

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

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

TDDC76 - Programmering och Datastrukturer

Tentamen Datastrukturer (DAT036)

Datastrukturer i kursen. Föreläsning 8 Innehåll. Träd rekursiv definition. Träd

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

Malmö högskola 2007/2008 Teknik och samhälle

Innehåll. Parametriserade typer. Klassmallar. Klassmallen Vektor Konstructor med std::initializer_list. Klassmallen Vektor Medlemsfunktioner

Föreläsning 9 Innehåll

Föreläsning Datastrukturer (DAT036)

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

TDIU01 - Programmering i C++, grundkurs

Dynamisk bindning och polymorfism

Tentamen EDAF30 Programmering i C++

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

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

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

Tentamen i TDP004 Objektorienterad Programmering Lösningsförslag

Föreläsning 7. Träd och binära sökträd

Träd. Ett träd kan se ut på detta sätt:

Föreläsning 9 Innehåll

JAVA Mer om klasser och objektorientering

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 8 Erik Nilsson, Institutionen för Datavetenskap, LiU

TDIU01 - Datortenta (DAT2)

Det finns många flaggor till g++,

Java, klasser, objekt (Skansholm: Kapitel 2)

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

Inlämningsuppgiften. Föreläsning 9 Innehåll. Träd. Datastrukturer i kursen

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

Inledande programmering med C# (1DV402) Tärningarna ska kastas

Transkript:

TDIU01 Programmering i C++ Föreläsning 6 - Klasser Eric Elfving, eric.elfving@liu.se Institutionen för datavetenskap (IDA) Avdelningen för Programvara och system (SaS)

Klasser När vi skapade vår lista gjorde vi det genom att definiera en pekare till en posttyp och fria funktioner som kunde manipulera en sådan pekare. Detta har dock vissa nackdelar: Eftersom användaren (programmeraren som skapar huvudprogrammet) vet att det är en pekare kan den manipulera den som en pekare. Eftersom vi måste ha en nollpekare från början (vårt sätt att se att det är en tom lista) kräver vi av användaren att pekaren sätts till noll. Om den inte nollställs ger det stora problem i vår kod. Dessa problem (och andra) kan vi lösa med klasser. En klass är en beskrivning av en datatyp. Genom att göra om vår lista till en klass kan vi dels dölja våra pekare (datarepresentation) samt få en bättre koppling mellan data och funktioner för att manipulera datat. Detta ska vi öva på under lektion och på lab.

Klasser En klass har två delar, en privat del och en publik del. I den publika delen lägger vi saker som vi vill att alla ska kunna komma åt, t.ex. metoder för att operera på vårt data. I den privata delen lägger vi det vi vill gömma för användaren, t.ex. datamedlemmar och hjälpfunktioner. class Klass public: Klass(); ~Klass(); void metod(); void const_metod() const; private: int data; ; Datamedlem void helper_function(); Metoder / medlemsfunktioner

Användning av klasser Vi kan se en klass som en beskrivning av en typ. Därför kan vi skapa en variabel (ett objekt) utifrån en klass precis som vi skapar en variabel av en grundläggande typ. För att sedan anropa en metod använder vi punktoperatorn.

Metoder En funktion som är med i en klass kallas metod eller medlemsfunktion. De fungerar i grunden som vanliga funktioner men har alltid tillgång till objektets datamedlemmar. I klassdefinitionen deklarerar man metoder precis som man gör med vanliga funktioner. Det finns dock ett specialfall; när man har en metod som inte ändrar på objektets datamedlemmar bör den deklareras som en const-metod. Då kan den användas på ett const-objekt. class Klass public: void set_value(int); int get_value() const; private: int data; void helper_function(); ;

Speciella metoder Det finns alltid minst fyra metoder för en klass: Konstruktor skapar ett objekt Destruktor tar bort ett objekt Kopieringskonstruktor och Kopieringstilldelningsoperator Om vi inte deklarerar någon av dessa själva kommer vi få en genererad av kompilatorn.

Konstruktor Konstruktorn är en speciell metod som finns för alla klasser. Den anropas när ett objekt skapas och används främst för att initiera datamedlemmar. Konstruktorn kan ta 0,1 eller flera parametrar, har samma namn som klassen och ingen returtyp. Klass() data = 0; Klass() :data(0) Klass(int d) data = d; Klass(int d) :data(d) Till höger ser vi användandet av en initieringslista. Den används för att initiera datamedlemmar Används såhär: Klass k; // Konstruktorn utan argument anropas Klass k2(2); // Konstruktorn med en parameter anropas

Destruktor Destruktorn anropas innan ett objekt förstörs. Dess huvudsakliga uppgift är att återlämna resurser som vår klass använt under dess livstid. Det vanligaste är att man återlämnar dynamisk allokerat minne men det kan också handla om att t.ex. stänga filer eller avsluta en nätverkskontakt. Om klassens datamedlemmar endast har enkla datatyper behövs sällan en egendefinierad destruktor, utan den kompilatorgenererade duger fint. class Klass public: Klass(); void metod(); void const_metod() const; private: int data; ; void helper_function(); class Klass2 public: Klass2(int d) Data = new int(d); ~Klass2() delete data; private: int * data; ;

Kopiering Det finns två sätt att kopiera objekt; med kopieringskonstruktor och med kopieringstilldelning. Kopieringskonstruktorn är en konstruktor med vilken man kopierar ett redan existerande objekt. Klass(const Klass & other) : data(other.data) Klass & operator=(const Klass &other) data = other.data; return *this; Kopieringstilldelningsoperatorn (tilldelning) används för att ändra värden på ett redan existerande objekt så att det blir en kopia av något annat objekt. int main() Klass k1(2); Klass k2(k1); Klass k3; k3 = k1; // // // // konstruktorn för heltal kopieringskonstruktor default konstruktor kopieringstilldelning

Kopiering, fortsättning Om man inte deklarerar kopieringskonstruktorn eller kopieringstilldelningsoperatorn kommer vi som sagt få en kompilatorgenererad. Men vad händer om vi inte vill tillåta kopiering? Vi kan förbjuda kopiering genom att deklarera båda metoderna i privata delen av vår klass. Därmed ser kompilatorn att de finns med men eftersom de ligger privat så kan inte användaren komma åt dem. Detta rekommenderar vi att ni gör för listklassen ni ska bygga för att slippa problem med grund kopiering.

Träd Nu gör vi om trädstrukturen vi hade förra föreläsningen till en klass. Till vänster är den gamla koden och till höger har vi den nya.

Träd header-filen (Tree.h) #include <iosfwd> class Tree public: #ifndef TREE_H #define TREE_H #include <iosfwd> typedef struct Tree_Node *Tree; void void bool void insert(int, Tree &); print(std::ostream &, Tree, int = 1); member(int, Tree); clear(tree &); #endif Tree() : root_(0) ~Tree(); void void bool void bool insert(int); print(std::ostream & = std::cout, int = 1) const; member(int) const; clear(); empty() const; private: // Dold kopieringskonstruktor och kopieringstilldelningsoperator // för att förhindra kopiering Tree(const Tree&); Tree &operator=(const Tree &); typedef struct Tree_Node * Sub_Tree; Sub_Tree root_; // rekursiva hjälpfunktioner void insert(int, Sub_Tree&); void print(ostream &, const Sub_Tree, int) const; bool member(int, const Sub_Tree) const; ;

Träd cc-filen (Tree.cc) #include <iostream> #include <iomanip> using namespace std; #include "Tree.h" struct Tree_Node int data; Tree left; Tree right; ; /* * create_leaf skapar en lövnod med det värde som skickas in */ void create_leaf(int data, Tree &tree) tree = new Tree_Node; tree >data = data; tree >left = 0; tree >right = 0; #include <iostream> #include <iomanip> using namespace std; #include "Tree.h" struct Tree_Node Tree_Node(int data, Tree_Node * left = 0, Tree_Node * right = 0) : data_(data), left_(left), right_(right) ~Tree_Node() delete delete left_ right_ left_; right_; = 0; = 0; int data_; Tree_Node * left_; Tree_Node * right_; ;

/* *insert stoppar in ett värde som ett löv i trädet. Om * värdet redan finns görs inget */ void insert(int data, Tree &tree) /* * insert stoppar in ett värde som ett löv i trädet. * Om värdet redan finns görs inget */ void Tree::insert(int data, Sub_Tree &tree) if (tree == 0) if (tree == 0) create_leaf(data,tree); tree = new Tree_Node(data); else if (tree >data_ > data) else if (tree >data > data) insert(data, tree >left_); insert(data, tree >left); else if (tree >data_ < data) else if (tree >data < data) insert(data, tree >right_); insert(data, tree >right); void Tree::insert(int data) insert(data, root_);

/* * print skriver ut trädet in order med höger delträd först * följt av noden och därefter vänster delträd. Detta gör att * man ser trädet rätt om man vrider skärmen (eller huvudet) 90 grader */ void print(ostream &os, Tree tree, int indent) if (tree == 0) return; void Tree::print(ostream &os, const Sub_Tree tree, int indent) const if (tree == 0) return; // Ett tomt träd ska inte skrivas ut if (tree >right!= 0) print(os,tree >right,indent+2); cout << setw(indent+1) << / << endl; if (tree >right_!= 0) // skriv ut höger subträd om det existerar cout << setw(indent) << tree >data << endl; cout << setw(indent) << tree >data_ << endl; // skriv ut nuvarande nod if (tree >left!= 0) cout << setw(indent+1) << \\ << endl; print(os,tree >left,indent+2); if (tree >left_!= 0) // skriv ut höger subträd om det existerar cout << setw(indent+1) << \\ << endl; print(os,tree >left_, indent+2); print(os,tree >right_, indent+2); cout << setw(indent+1) << / << endl; void Tree::print(ostream &os, int indent) const print(os, root_,indent);

/* * member returnerar true om värdet finns i trädet, annars false */ /* * member returnerar true om värdet finns i trädet, annars false */ bool member(int data, Tree tree) bool Tree::member(int data, const Sub_Tree tree) const if (tree == 0) return false; if (tree == 0) return false; else if (tree >data_ == data) return true; else if (tree >data_ == data) return true; else if (tree >data_ > data) return member(data, tree >left_); else if (tree >data_ > data) return member(data, tree >left_); return member(data, tree >right_); return member(data, tree >right_); bool Tree::member(int data) const return member(data, root_);

/* * clear tar bort ett träd rekursivt genom att först anropa clear * för subträden och sedan återlämna sig själv */ void clear(tree &t) if (t!= 0) clear(t >left); clear(t >right); delete t; t = 0; /* * clear behövs inte längre utan vi kan skapa en * destruktor istället. Om vi vill att användaren * ska få explicit tömma en lista kan det dock * vara bra att lämna kvar clear. */ Tree::~Tree() delete root_; root_ = 0; /* * empty undersöker om trädet är tomt eller ej. */ bool Tree::empty() const return root_ == 0;

Träd huvudprogrammet (tree_main.cc) #include <iostream> #include <iomanip> using namespace std; #include "Tree.h" int main() Tree tree = 0; for (int i = 0; i<5; ++i) insert(i,tree); #include <iostream> #include <iomanip> using namespace std; #include "Tree.h" int main() Tree tree; for (int i = 0; i<5; ++i) tree.insert(i); print(cout, tree); clear(tree); tree.print(); tree.clear(); if (tree == 0) cout << endl <<"Trädet är nu tomt" << endl << endl; if (tree.empty()) cout << endl <<"Trädet är nu tomt" << endl << endl; insert(5, tree); insert(2, tree); insert(1, tree); tree.insert(5); tree.insert(2); tree.insert(1); print(cout, tree); tree.print(cout); cout << boolalpha << member(0, tree) << endl; cout << boolalpha << tree.member(0) << endl;

Objektorientering???

www.liu.se