52
C++ for Java- programmerere Åsmund Eldhuset for TDT4102 asmunde *at* stud .ntnu.no http://folk.ntnu.no/asmunde/tdt4102- studasskurs-2009.ppt

C++ for Java-programmerere

  • Upload
    hieu

  • View
    59

  • Download
    0

Embed Size (px)

DESCRIPTION

C++ for Java-programmerere. Åsmund Eldhuset for TDT4102 asmunde *at* stud .ntnu.no http://folk.ntnu.no/asmunde/tdt4102-studasskurs-2009.ppt. Forutsetninger. Du er noenlunde komfortabel med Java Du kjenner følgende konsepter innen objektorientert programmering: Klasser Innkapsling Arv - PowerPoint PPT Presentation

Citation preview

Page 1: C++ for Java-programmerere

C++ for Java-programmerere

Åsmund Eldhusetfor TDT4102

asmunde *at* stud.ntnu.nohttp://folk.ntnu.no/asmunde/tdt4102-studasskurs-2009.ppt

Page 2: C++ for Java-programmerere

Forutsetninger

Du er noenlunde komfortabel med Java Du kjenner følgende konsepter innen

objektorientert programmering: Klasser Innkapsling Arv Polymorfi Grensesnitt (interfaces)

Page 3: C++ for Java-programmerere

Litt historie

C ble utviklet på 70-tallet av Brian W. Kernighan og Dennis M. Ritchie

Designet for systemprogrammering under UNIX C++ ble utviklet på 80-tallet av Bjarne Stroustrup Bygger på C; første utgave het "C with classes" Hentet mange ideer fra norskutviklede Simula

(verdens første objektorienterte språk) Både C og C++ er åpne og ISO-standardiserte

Page 4: C++ for Java-programmerere

Argumenter for C++

Raskere enn Java Java kjøres av en Virtual Machine C++ kompileres til maskinkode

Gir nærkontakt med systemet Innfallsport til C, som er enda bedre egnet til system-

programmering (operativsystemer, mikrokontrollere etc.)

Du kan gjøre ALT som er mulig å gjøre med datamaskinen

Ett av de mest utbredte programmeringsspråkene; mange eksisterende systemer er skrevet i C++

Mange ferdigskrevne biblioteker Nerdefaktor ;-)

Page 5: C++ for Java-programmerere

Argumenter mot C++

Mindre nybegynnervennlig Lett å skyte seg selv så til de grader i foten Uforsiktighet kan føre til obskure

minnelekkasjer Portabiliteten varierer med hva man foretar

seg Utvikling tar generelt sett lengre tid enn med

Java og C#

Page 6: C++ for Java-programmerere

Når bruke C++?

Når du trenger rå hastighet (spill, grafikk, tungregning, algoritmekonkurranser)

Når du driver systemprogrammering Når du arbeider med eksisterende C++-

systemer Når du har lyst til å leke deg med

programmering

Page 7: C++ for Java-programmerere

C++ vs. Java

Java Proprietært (Sun) Garbage collection Kjøres av en VM Samme kompilerte

kode kan kjøres overalt Bruker nesten samme

syntaks som C++

C++ Åpent Manuell

minnebehandling Kompileres til

maskinkode Må rekompileres for

hvert nye system; koden kan måtte endres

Page 8: C++ for Java-programmerere

Kompilatorer og IDE'er Kompilator oversetter koden til maskinkode IDE = Integrated Development Environment

(kombinerer editor, kompilator og debugger) Linux:

Kompilator: gcc / g++ Debugger: gdb Editor: det du foretrekker

Windows: Microsoft Visual Studio

(http://www.microsoft.com/express/vc) Bloodshed Dev-C++

(http://www.bloodshed.net/devcpp.html)

Page 9: C++ for Java-programmerere

Bruk av g++

Kompilering: g++ kildefil Kjøring: ./a.out Kompilere flere filer: g++ kilde1 kilde2 ...

Endre navnet til outputfilen:g++ -o outputfil kildefil./outputfil

Skyte seg selv i foten:g++ -o kildefil kildefil(sletter kildekoden din)

Page 10: C++ for Java-programmerere

Minimalt program

int main() { return 0;}

Vi legger merke til: Typen til main() er int, ikke void Ingen String [] args (skal programmet ta imot

argumenter, skriv int argc, char * argv []) main() er ikke public static

og står ikke inni noen klasse

Page 11: C++ for Java-programmerere

Del I: Grunnleggende C++

Page 12: C++ for Java-programmerere

Hello World

// Dette er et Hello World-program

#include <iostream>

using namespace std;

int main() { cout << "Hello World!" << endl; return 0;}

Page 13: C++ for Java-programmerere

Hello World

Kommentarer lages med // eller /* */ cout << x << endl; tilsvarer System.out.println(x);

#include minner om import, men fungerer ved å "lime inn" en fil (mer om dette senere)

iostream er et bibliotek som inneholder IO-støtte (f.eks. cout)

using namespace minner også om import. Uten dette måtte vi skrive std::cout og std::endl, fordi cout og endl tilhører et namespace (tilsv. en pakke) som heter std.

Man kan ha funksjoner utenfor klasser; main() skal alltid være en slik funksjon

Page 14: C++ for Java-programmerere

Input og output

cout << x; skriver data til skjermen cout << endl; skriver et linjeskift cin >> x; leser data fra tastaturet cin merker hvilken datatype variablene har cin og cout kan "cascade"s:cout << x << y << z; (skriver ut dataene uten mellomrom mellom)cin >> x >> y >> z; (leser først inn i x, så i y, så i z)

Page 15: C++ for Java-programmerere

Variabler Variabler lages og brukes på samme måte

som i Java C++ har følgende primitive datatyper:

bool (tilsvarer boolean) char (tilsvarer byte og til en viss grad char) short int long float double

unsigned kan brukes foran heltallstypene Funksjoner kan også ha void som type

Page 16: C++ for Java-programmerere

If/else, for, while

... fungerer på samme måte som i Java! Kun én forskjell: betingelser i if/else og while

kan være heltall (0 blir false, alt annet blir true)

int x, y;cin >> x >> y;if (y) cout << x / y << endl;else cout << "Nevneren er 0!" << endl;

Page 17: C++ for Java-programmerere

Deklarasjon av funksjoner

Før en funksjon brukes, må kompilatoren vite at funksjonen eksisterer

Dette kan gjøres på to måter: Funksjonen kan allerede være definert (dvs. at

funksjonskoden står lenger oppe i kodefilen) Definisjonen kan finnes i en annen fil, og

funksjonen kan deklareres (dvs. at man bare skriver metodenavnet)

Eksempel: funksjonenint square(int n) { return n * n; }kan deklareres slik:int square(int);

Page 18: C++ for Java-programmerere

Biblioteker og headerfiler C++-kompilatoren kompilerer én fil av gangen

uavhengig av alle de andre Biblioteksfunksjonene ligger i ferdigkompilerte

filer Headerfiler inneholder deklarasjoner som

forteller hvordan biblioteksfunksjonene ser ut Hvis f.eks. kompilatoren ser int square(int);,

stoler den på at det finnes en slik funksjon. Den kompilerer koden som bruker square() og prøver etterpå å koble inn square() sin egen kode

Sammenkoblingsprogrammet kalles for en linker, og er som regel en del av kompilatoren

Page 19: C++ for Java-programmerere

Biblioteker og headerfiler

Man kan selv lage prosjekter som består av flere kodefiler Koden deles opp i kodefiler (.cpp) og headerfiler

(.h) Headerfilene inneholder deklarasjoner (navn og

parameterlister for metoder og klasser) Kodefilene inneholder definisjoner (den faktiske

implementasjonen / koden) #include "limer inn" koden fra en fil, og skal bare

brukes for å inkludere headere

Page 20: C++ for Java-programmerere

Del II: Pekere

Page 21: C++ for Java-programmerere

Pekere

En variabel som inneholder en minneadresse Bruk * i deklarasjoner for å lage

"peker-til-datatype" Bruk & for å finne adressen til en variabel Bruk * for å dereferere en peker (lese innholdet i

adressen det pekes til) C++ bruker NULL i stedet for null int a = 42;int * p = NULL;p = &a;cout << p << endl;cout << *p << endl;

p42a

0x32p

42a

0x04 0x32

Page 22: C++ for Java-programmerere

p q

Triksing med pekere

int a = 3;int * p, * q;p = &a;q = &a;*p = 42;cout << a << endl;cout << *q << endl;

3a42

Page 23: C++ for Java-programmerere

Peker-til-peker-til...

int a, * p, ** q, *** r;a = 42;p = &a;q = &p;r = &q; cout << r << endl;cout << *r << endl;cout << **r << endl;cout << ***r << endl;

q

p

42a

r

Page 24: C++ for Java-programmerere

Funksjonsargumenter Alle argumenter sendes som kopi Følgende gir dermed ikke det tenkte resultatet:void swap(int a, int b) { int temp = a; a = b; b = temp;}

Vi sender pekere i stedet, for da får vi modifisert dataene gjennom pekerne:void swap(int * a, int * b) { int temp = *a; *a = *b; *b = temp;}

Sistnevnte funksjon må kalles slik: swap(&a, &b)

Page 25: C++ for Java-programmerere

Referanser

Et tredje alternativ er å bruke referanser En referanse er en mellomting mellom peker

og "rådata" Er ikke en kopi av dataene, så endring av en

referanse fører til endring av de originale dataene Kan ikke være NULL Aksesseres som om det var rådata

void swap(int & a, int & b) { int temp = a; a = b; b = temp;}

Kalles slik: swap(a, b)

Page 26: C++ for Java-programmerere

Arrays

Et array er bare et sammenhengende minneområde av samme datatype

En peker kan derfor brukes til å peke til starten av et array

Arrays lages slik:int * array = new int [4];array

Page 27: C++ for Java-programmerere

Arrays

Arrays er 0-indekserte og aksesseres som i Java:array[2] = array[1] + array[0];

Bak kulissene foregår oppslag på array[i] slik: Adressen i array leses Størrelsen til datatypen som array peker til

ganges med i og adderes til adressen for å finne hvor dataene ligger

array

4 bytes

0x32 0x36 0x40 0x44

0x32

Page 28: C++ for Java-programmerere

Arrays

Arrays vet ikke hvor store de er, og du får ingen exception hvis du går utenfor grensene int * array = new int [8];for (int i = -1; i <= 8; ++ i)

cout << array[i] << endl; Ingen feilmelding Du får ut data Programmet kan krasje noen ganger, og fortsette

andre ganger Etter bruk må et array slettes:delete [] array;

Page 29: C++ for Java-programmerere

Flerdimensjonale arrays

int ** array = new int * [3];for (int i = 0; i < 3; ++ i) array[i] = new int [4];

array

Page 30: C++ for Java-programmerere

Del III: Objektorientering og minnebehandling

Page 31: C++ for Java-programmerere

Klassedeklarasjoner Klasser i C++ kan ikke være public/private Deklarasjon og definisjon bør skilles Deklarasjonen avsluttes med et semikolon Constructors fungerer som i Java Deklarasjon:class Person { Person(std::string name, int age); void presentYourself(); std::string name; int age;};

Page 32: C++ for Java-programmerere

Klassedefinisjoner this er en peker, og man bruker -> for å

lese medlemmer via pekere Person::Person(string name, int age) { this->name = name; this->age = age;}

void Person::presentYourself() { cout << "Hei, jeg heter " << name << " og er " << age << " år gammel." << endl;}

Page 33: C++ for Java-programmerere

Innkapsling

Tre nivåer: public, protected, private public og private er det samme som i Java Siden C++ ikke har pakker, finnes ikke

package/default visibility, og protected gir synlighet bare for subklassene

I stedet for å sette modifikatoren foran hver variabel/funksjon, setter man den som "overskrift"

Page 34: C++ for Java-programmerere

Innkapsling

class Person {public: Person(std::string name, int age); void presentYourself();private: std::string name; int age;};

Page 35: C++ for Java-programmerere

Objekter Man har både objektvariabler og objektpekere

Objektvariabler inneholder selve objektet, og oppfører seg som om det var en variabel av primitiv datatype – forsvinner automatisk når funksjonen avsluttes

Objektpekere oppførerer seg som Java sine objektvariabler – må allokeres og deallokeres

. brukes på objektvariabler, og -> på objektpekere Objektvariabler:Person p("Aasmund", 20);p.presentYourself();

Objektpekere:Person * p = new Person("Aasmund", 20);p->presentYourself();delete p;

Page 36: C++ for Java-programmerere

Arv Tre typer arv: public, protected og private

Vi skal bare se på public, som tilsvarer Java sin type arv

C++ har ikke noe Object som alle klasser arver implisitt (du kan lage et selv hvis du vil, men det vil bare funke for dine egne klasser, ikke de innebygde)

C++ støtter multiple inheritance, dvs. at en klasse kan arve fra flere klasser

Java: class Professor extends PersonC++: class Professor : public Person

Page 37: C++ for Java-programmerere

Virtuelle funksjoner

Hvis du har følgende i Java:Person p = new Professor();p.presentYourself();er det Subclass sin versjon av someFunction() som kjøres

For å få til dette i C++ må man sette virtual foran funksjonsnavnet

Ikke-virtuelle funksjonskall bestemmes ved kompileringstid ut i fra pekertypen

Virtuelle funksjonskall bestemmes ved kjøretid ut fra den egentlige typen til objektet

Page 38: C++ for Java-programmerere

Abstrakte klasser og funksjoner

Abstrakte funksjoner kalles for "pure virtual" C++ har ikke abstract Sett = 0 etter en funksjon for å gjøre den

abstrakt:int someAbstractFunction(int x) = 0;

Klasser som inneholder "pure virtual"-funksjoner blir automatisk abstrakte (selv hvis de inneholder vanlige funksjoner også)

Page 39: C++ for Java-programmerere

Abstrakte klasser og funksjoner Java:public abstract class BankAccount { private int balance; public abstract void deposit(int);}

C++:class BankAccount {public: void deposit(int) = 0;private: int balance;};

Page 40: C++ for Java-programmerere

Abstrakte klasser og funksjoner

Abstrakte klasser kan ikke instansieres new BankAccount() er ikke tillatt

Subklasser som ikke implementerer alle "pure virtual"-funksjoner blir også abstrakte

class SavingsAccount() : public BankAccount {public: void deposit(int amount) { this->balance += amount - 100; }};

Page 41: C++ for Java-programmerere

Interfaces

C++ har ikke interfaces, men variabelløse, abstrakte klasser gjør samme nytten

Java:public interface IRobberyVictim { void getRobbed(int amount);}

C++:class IRobberyVictim {public: virtual void getRobbed(int amount) = 0;};

Page 42: C++ for Java-programmerere

Interfaces

Java:public class Person implements RobberyVictim

C++:class Person : public RobberyVictim

Page 43: C++ for Java-programmerere

Arrays med objekter Primitive typer:int * intArray = new int [4];

Objekter:Car * carArray = new Car [4];

Objektpekere:Car ** carPointerArray = new Car * [4];for (int i = 0; i < 4; ++ i) carPointerArray[i] = new Car();

Page 44: C++ for Java-programmerere

Arrays med objektera

a[0] a[1] a[2] a[3]

car

car[0] car[1] car[2] car[3]

Page 45: C++ for Java-programmerere

Arrays med objektercp

cp[0] cp[1] cp[2] cp[3]

*cp[0]

*cp[1]

*cp[2]

*cp[3]

Page 46: C++ for Java-programmerere

Minnebehandling C++ har ingen garbage collector Du er selv ansvarlig for å frigi minne du ikke

trenger lenger Verktøy for dette: delete, delete [],

destructors Regler for trygg minnebehandling:

Ta alltid vare på resultatet fra new Hver gang du skriver new, husk å plassere en delete på et passende sted

Et objekt som new'er noe bør vanligvis også delete det (bruk destructors)

Page 47: C++ for Java-programmerere

Destructors

Klasser kan definere en destructor (bare én, uten parametre), som vil kalles når objektet destrueres (enten med delete eller når en automatisk (dvs. lokal) variabel går ut av scope)

Syntaks:class MyClass {public: ~MyClass();};

MyClass::~MyClass() { ... }

Page 48: C++ for Java-programmerere

delete og delete [] delete frigir minne for et enkelt objekt/primitiv type:int * a = new int;delete a;Car * c = new Car();delete c;

Hvis delete kalles på en objektpeker, kaller den destructoren til objektet før minnet frigis

delete [] frigir minne for et array Bruk aldri delete på noe du lagde med new [], og

bruk ALDRI delete [] på noe du lagde med new For de som kan C: Bruk ALDRI free() på noe du

lagde med new eller delete på noe du lagde med malloc()

Page 49: C++ for Java-programmerere

delete og delete []

delete [] på et objektarray kaller destructors:

Car * carArray = new Car [4];delete [] carArray;

delete [] på et objektpekerarray kaller ikke destructors, så det må deallokeres slik:Car ** carPointerArray = new Car * [4];for (int i = 0; i < 4; ++ i) carPointerArray[i] = new Car();for (int i = 0; i < 4; ++ i) delete carPointerArray[i];delete [] carPointerArray;

Page 50: C++ for Java-programmerere

Templates

Tilsvarer generics i Java. Lar deg skrive generisk kode som fungerer med flere datatyper

template<typename T>void swap(T * a, T * b) { T temp; temp = *a; *a = *b; *b = temp;}

Hver gang du bruker en template-funksjon på en bestemt datatype, lages en ny utgave av koden for funksjonen (ulikt hvordan det er implementert i Java)

Page 51: C++ for Java-programmerere

Operator overloading Dette gjør at du kan få operatorer til å fungere på

egendefinerte klasser F.eks. kan man ha en vektor-klasse, og så definere + til å

bety vektoraddisjon (når + står mellom to vektorer), - til å bety vektorsubtraksjon og * til å bety prikkprodukt

Kan misbrukes – vær påpasselig med å bare definere meningsfylte og intuitive operasjoner (ikke bruk + til subtraksjon)

En operator kan overloades som: En medlemsfunksjon (gir operatoren full tilgang til objektdataene,

men venstre operand må være et objekt av samme type) Som en friend-funksjon (gir også full tilgang) En frittstående funksjon (gir bare tilgang vha. getters og setters)

Page 52: C++ for Java-programmerere

Noen nyttige linker

C++ FAQ Lite: http://www.parashift.com/c++-faq-lite

C++ FQA Lite:http://yosefk.com/c++fqa/

STL-dokumentasjon (Standard Template Library):http://www.sgi.com/tech/stl/

En av mange C++-tutorials (det er bare å søke etter flere): http://www.cplusplus.com/doc/tutorial/

For de avanserte som vil prøve seg på grafikkprogrammering: http://nehe.gamedev.net/

De klassiske vitsene om selvskudd i foten:http://www-users.cs.york.ac.uk/susan/joke/foot.htm