F8: Typkonvertering i C++



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

OOP Objekt-orienterad programmering

Introduktion till arv

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

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

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

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

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

Tillämpad programmering

TDDC76 - Programmering och Datastrukturer

Tentamen i TDP004 Objektorienterad Programmering Teoretisk del

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

Tentamen i TDP004 Objektorienterad Programmering Lösningsförslag

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

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

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

Dynamisk bindning och polymorfism

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

Introduktion. Lagom är bäst. OO eller ej? TDP004 Objektorienterad Programmering Fö 7 Objektorienterad design, tips och råd

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

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

OOP Objekt-orienterad programmering

Skapa, kopiera och destruera klassobjekt

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Felsökning. Datatyper. Referenstyper. Metoder / funktioner

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

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

Typecasting - primitiva typer. Innehåll. DoME klasser

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

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

Synlighet. Namespace Scope-operatorn Klasser Vänner

Klasshierarkier - repetition

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

Kapitel 6 - Undantag

Typkonvertering. Java versus C

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

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

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

Arv Murach s: kap 14

TENTAMEN. Kurs: Objektorienterad programmeringsmetodik 5DV133 Ansvarig lärare: Anders Broberg. VT-13 Datum: Tid: kl

TDDC76 - Programmering och Datastrukturer

Innehåll. Pekare Exempel

DIAGNOSTISKT PROV. Tid. Hjälpmedel. Antaganden. Rättning. Övrigt. Diagnostiskt Prov. Klockan Inga

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

Innehåll. Pekare Exempel

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

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

TDDC76 - Programmering och Datastrukturer

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

Det finns många flaggor till g++,

Statistik över heltal

Konstruktion av klasser med klasser

Kopiering av objekt i Java

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

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

TDIU01 - Programmering i C++, grundkurs

TDDC76 Programmering och datastrukturer

Subtyping och variance. Objekt-orienterad programmering och design Alex Gerdes, 2018

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

Classes och Interfaces, Objects och References, Initialization

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

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

Objektorienterad Programmering (TDDC77)

TENTAMEN I DATAVETENSKAP

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

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

Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Jonas Lindgren, Institutionen för Datavetenskap, LiU

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

Diagnostiskt Prov. Antaganden Om förutsättningar saknas I en uppgift skall rimliga antaganden göras och nedtecknas.

Objektorienterad Programmering (TDDC77)

Innehåll. 1 Funktionsmallar. 2 Pekare och konstanter. 3 Typomvandlingar. struct Name { string s; //... };

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

Arv innebär att man skapar en ny klass (subklass) utifrån en redan existerande klass (superklass, basklass).

F8 - Arv. ID1004 Objektorienterad programmering Fredrik Kilander

Tillämpad programmering

Objektorienterad programmering Föreläsning 8. Copyright Mahmud Al Hakim Agenda (halvdag)

I Skapa Hej.java och skriv programmet. I Kompilera med javac Hej.java. I Rätta fel och repetera tills du lyckas kompilera ditt program

OOP Objekt-orienterad programmering

F4 Klasser och Metoder. ID1004 Objektorienterad programmering Fredrik Kilander

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

Arv. Objektorienterad och komponentbaserad programmering

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Strukturdiagram. Styra. Algoritmer. Val

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

allokeras på stacken dynamiskt new delete

Grundläggande programmering, STS 1, VT Sven Sandberg. Föreläsning 14

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

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

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

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

Lösningar för tenta 2 DAT043,

Minneshantering. Minneshantering. Minneshantering. Undvik pekare

Översikt MERA JAVA OCH ECLIPSE. Uttryck och tilldelning. Uttryck och tilldelning. Uttryck och tilldelning. Uttryck och tilldelning

Classes och Interfaces, Objects och References Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

TDA550 Objektorienterad programmering, fortsättningskurs. Föreläsning 1. Introduktion Variabler och typer

OOP Objekt-orienterad programmering

Enkla variabler kontra referensvariabel

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

DELPROV 1 I DATAVETENSKAP

TDIU01 Programmering i C++

Kort repetition. Programmeringsteknik för Bio1 och I1. Vad ska vi lära oss idag? Ett exempel

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

Transkript:

Institutionen för datavetenskap Umeå Universitet F8: Typkonvertering i C++ Objektorienterad programmering för ingenjörer, VT04

Innehåll Implicit konvertering Konverteringskonstruktor Konverteringsoperator Explicit konvertering static_cast dynamic_cast const_cast reinterpret_cast Virtuella arv Felaktig arvsdesign down casting 04-05-25 2

Typkonvertering Implicit konvertering T.ex. double a = 6.0; double b = a / 4; 4 konverteras till double automatiskt int b = a / 4; Ger olika resultat Explicit konvertering T.ex. double d = a / (double)4; Hur hanteras då egen-definerade typer? T.ex. konvertering av klassen A till int <-- vad händer då? 04-05-25 3

Implicit konvertering Konverteringskonstruktor A::A(const B& rhs) A::A(const string& rhs) A::A(int rhs) A::A(char*) Konverteringsoperator A::operator B() const A::operator string() const A::operator int() const A::operator char*() const Notera att ingen returtyp är deklarerad men funktionen måste ändå returnera ett värde Kan vara källa till fel! Oönskad konvertering sker... kompilatorn vill för mycket 04-05-25 4

Implicit konvertering A a = 5.0; Konverteringsoperator från int är deklarerad Fel typ 5.0 Konvertering till int 5 Konvertering till egendef. typ A 5 Typ: A int double 04-05-25 5 5

Implicit konvertering A a = 5; Om operator=(int) ej är deklarerad körs konverteringskonstruktorn A::A(int) a = 5; Om operator=(int) ej finns körs konverteringskonstruktorn (const char*)a; Konverteringsoperatorn A::operator const char*() const körs b = (const char*)a; Konverteringskonstruktorn och konv-operator körs b = 5.0; Krångligt!? Om double-konvertering inte finns men int-konvertering finns konverteras 5.0 implicit till en int! 04-05-25 6

Implicit konvertering Det finns en förklaring... Konverteringskonstruktorn anropas när ett temporärt objekt måste skapas och konvertering krävs a = 5; ==> a = A(5) Konverteringsoperatorn anropas när konvertering krävs och ett temporärt objekt ej behöver skapas (const char*)a; vid b = (const char*)a; så skapas även ett temporärt objekt och konverteringskonstruktorn anropas också Om operator=(int) finns så behövs ingen konvertering göras 04-05-25 7

Exempel convop.cc 04-05-25 8

Explicit konverting 4 typer av konverteringar static_cast<t>() dynamic_cast<t>() const_cast<t>() reinterpret_cast<t>() Ger viss kontroll till hur typer konverteras 04-05-25 9

static_cast Konvertera uttrycket v till typen T static_cast<t>(v) Bör ej ta bort const-villkor static_cast<char*>(getvalue()) <-- där getvalue() returnerar const char* Ett uttryck e kan konverteras till T förutsatt att konverteringsoperationer är deklarerade static_cast<t>(e) <-- ger T t(e) där t är ett temporärt objekt A a = static_cast<a>('x'); blir A a('x'); men det kan ju kompilatorn klara implicit? Ger lite mer kontroll eftersom nu sker konvertering som DU vill Betyder detta att static_cast endast fungerar i de fall implicit konvertering fungerar? 04-05-25 10

static_cast Nej... den kan även göra följande konverteringar Från godtycklig typ till void Från en basklass till en subklass-referens Exempel static_cast<void*>(&b);// ekvivalent med (void*)&b; static_cast<int>(b); // ekvivalent med (int)b; eller int(b); Derived derived; Base& base = derived; static_cast<derived&>(base); Base base1; static_cast<derived&>(base1); <-- odef. beteende 04-05-25 11

static_cast Fortsättning exempel char* p; void* v; v = p; // OK p = v; // Error (ingen implicit konverting finns) p = static_cast<char*>(v)// OK (explicit konvertering) 04-05-25 12

dynamic_cast Navigera i en arvhierarki Run-time konvertering (polymorfism) Basklass Subklass Konvertering kan ske compile-time static_cast Konvertering kan endast ske run-time dynamic_cast 04-05-25 13

dynamic_cast Kan indikera om en konvertering misslyckats Konvertering av pekare 0 returneras vid felaktig konvertering Konvertering av referens Bad_cast-undantag kastas Exempel Base* base; Derived derived; base = &derived; Derived* d = dynamic_cast<derived*>(base); 04-05-25 14

const_cast Tar bort const från en typ Exempel Funktionen f() double f(double& d); f() vill anropas från funktionen g() void g(const double& d) { val = f(d); } Kompilatorn klagar eftersom f() kan ändra d void g(const double& d) { val = f(const_cast<double&>(d)); } 04-05-25 15

reinterpret_cast Konvertering mellan två helt orelaterade typer Kan användas för att konvertera en pekare till en int Kompilatorspecifikt beteende Minskar portabilitet av kod <-- bör undvikas! För mer information om explicit konvertering Bowden Wise, G.: Casting in C++: Bringing Safety and Smartness to Your Programs http://www.acm.org/crossroads/xrds3-1/ovp3-1.html (2004-04-28) 04-05-25 16

String-klassen Varför finns då inte en konverteringsoperator från string till char*? konverteringskonstruktor från char* string s = Vi älskar typkonvertering ; kopieringskonstruktor och tilldelningsoperator string t(s); string t = s; Om det då fanns en konvertering från string->char* string s = t; Är t en char* eller en string? Funktionen c_str() returnerar en char* 04-05-25 17

Virtuella arv Löser en del problem med multipel arv Vehicle Vehicle Car Jet JetCar 04-05-25 18

Virtuella arv Skapar endast en kopia av basklassen Vehicle virtual virtual Car Jet JetCar 04-05-25 19

Virtuella arv Klassen längst ned i hierarkin ansvarar för att initiera den virtuella basklassen I det vanliga fallet initierar subklassen klassen direkt ovan i hierarkin Exempel class Vehicle { Vehicle(string) { } }; class Car : virtual public Vehicle { }; class Jet : virtual public Vehicle { }; class JetCar : public Jet, public Car { JetCar(string) : Vehicle( call base class ) { } }; 04-05-25 20

Arvsdesign Bra arvsdesign är mycket svårt Typkonvertering nedåt i arvshierarki är oftast en indikation på dålig design Ett exempel på dålig arvsdesign Banksystem-exempel Delsystem som administrerar bankkonton 04-05-25 21

Banksystemet Tar fram en basklass class BankAccount { public: virtual ~BankAccount() = 0; virtual void deposit_money(double amount) = 0; virtual void withdraw_money(double amount) = 0; virtual double balance() = 0; }; Skapar även en array som håller alla konton BankAccount* all_accounts[num_accounts]; 04-05-25 22

Banksystemet I nuläget endast ett sorts konto Ett sparkonto class SavingsAccount : public BankAccount { public: // Lägger till månadens ränta void credit_interest(); //... }; Lägga till ränta till på alla sparkonton (ränterutin) for (int i = 0; i!= n; ++i) { all_accounts[i]->credit_interest(); } Men det fungerade ju inte? 04-05-25 23

Banksystemet Vi vet ju att det är ett SavingsAccount så då berättar vi det för kompilatorn for (int i = 0; i!= n; ++i) { static_cast<savingsaccount*>(all_accounts[i])->credit_interest(); } Vi har just gjort en down cast Ett nytt krav dyker upp: Systemet skall kunna hantera check-konton som också är räntebärande class CheckingAccount : public BankAccount { public: void credit_interest(); //... }; Vad händer nu med ränterutinen? 04-05-25 24

Banksystemet Arrayen all_accounts kommer nu ha både sparkonton och checkkonton Ränterutinen hanterar bara sparkonton i dagsläget Det löser vi enkelt tänker vi... for (int i = 0; i!= n; ++i) { if (/* all_acounts[i] pekar på ett SavingsAccount */) { static_cast<savingsaccount*>(all_accounts[i])->credit_interest(); } else { static_cast<checkingaccount*>(all_accounts[i])->credit_interest(); } } Detta blir en underhållsmardröm! 04-05-25 25

Banksystemet Olika lösningar på problemet: Identifiera vad sparkonton och checkkonton har gemensamt class InterestBearingAccount : public BankAccount { public: virtual void credit_interest() = 0; }; class SavingsAccount : public InterestBearingAccount {... }; class CheckAccount : public InterestBearingAccount {... }; for (...) if ( /* InterestBearingAccount */ ) {... } Begränsa kontolistan till att bara kunna innehålla InterestBearingAccount Finns ingen perfekt lösning... Om down cast måste ske använd dynamic_cast istället för static_cast, vilket då ger 04-05-25 26

Banksystemet for (int i = 0; i!= n; ++i) { BankAccount* a = all_accounts[i]; if (SavingsAccount* sa = dynamic_cast<savingsaccount*>(a)) sa->credit_interest(); else if (CheckingAccount* sa = dynamic_cast<checkingaccount*>(a) sa->credit_interest(); else // ERROR! } 04-05-25 27