Presentasjon lastes. Vennligst vent

Presentasjon lastes. Vennligst vent

C++ for Java-programmerere

Liknende presentasjoner


Presentasjon om: "C++ for Java-programmerere"— Utskrift av presentasjonen:

1 C++ for Java-programmerere
Åsmund Eldhuset for Abakus Fagkom asmunde *at* stud.ntnu.no Vil prøve å avdekke en del feller slik at dere slipper å skyte dere selv i foten i størst mulig grad, men har sikkert glemt både det ene og det andre... Husk å minne om at folk kan stille spørsmål

2 Forutsetninger Du er noenlunde komfortabel med Java
Du kjenner følgende konsepter innen objektorientert programmering: Klasser Innkapsling Arv Polymorfi Grensesnitt (interfaces)

3 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 Inspirert av BCPL og B UNIX ble senere skrevet på nytt i C

4 Argumenter for C++ Raskere enn Java Gir nærkontakt med systemet
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 ;-)

5 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#

6 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

7 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

8 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://msdn.microsoft.com/vstudio/express/visualc/) Bloodshed Dev-C++ (http://www.bloodshed.net/devcpp.html) MSVS kan lastes ned gratis fra

9 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)

10 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 Dette var jo ikke så ille?

11 Del I: Grunnleggende C++

12 Hello World // Dette er et Hello World-program
#include <iostream> using namespace std; int main() { cout << "Hello World!" << endl; return 0; }

13 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

14 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)

15 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

16 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;

17 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: funksjonen int square(int n) { return n * n; } kan deklareres slik: int square(int);

18 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

19 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

20 Del II: Pekere

21 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; p a 0x32 42 0x04 0x32 p a 42

22 Triksing med pekere int a = 3; int * p, * q; p = &a; q = &a; *p = 42;
cout << a << endl; cout << *q << endl;

23 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; r q p Kunne godt ha endret rekkefølgen på assignmentene; & endrer ingenting, og pekerassignment påvirker bare pekeren a 42

24 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) Illustrer på tavla

25 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)

26 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

27 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 0x32 4 bytes 0x32 0x36 0x40 0x44

28 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;

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

30 Del III: Objektorientering og minnebehandling

31 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; };

32 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; }

33 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"

34 Innkapsling class Person { public: Person(std::string name, int age); void presentYourself(); private: std::string name; int age; }; class BankAccount() { public: BankAccount(); void deposit(int amount); int withdraw(int amount); int getBalance(); private: int balance; };

35 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;

36 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 (men du kan lage et selv hvis du vil) C++ støtter multiple inheritance, dvs. at en klasse kan arve fra flere klasser Java: class Professor extends Person C++: class Professor : public Person

37 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

38 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å)

39 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; };

40 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) { balance += amount - 100; } };

41 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; };

42 Interfaces Java: public class Person implements RobberyVictim
C++: class Person : public RobberyVictim

43 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();

44 Arrays med objekter a a[0] a[1] a[2] a[3] car car[0] car[1] car[2]

45 Arrays med objekter cp cp[0] cp[1] cp[2] cp[3] *cp[3] *cp[2] *cp[1]

46 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 også delete det (bruk destructors)

47 Destructors Klasser kan definere en destructor (bare én, uten parametre), som vil kalles når objektet destrueres Syntaks: class MyClass { public: ~MyClass(); }; MyClass::~MyClass() { ... }

48 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()

49 delete og delete [] delete [] på et objektarray kaller destructors:
Car * carArray = new Car [4]; delete [] carArray; delete [] på et objektpekerarray kaller ikke destructors: 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;

50 Templates 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

51 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)

52 Noen nyttige linker C++ FAQ Lite: STL-dokumentasjon (Standard Template Library): En av mange C++-tutorials (det er bare å søke etter flere): For de avanserte som vil prøve seg på grafikkprogrammering: De klassiske vitsene om selvskudd i foten:


Laste ned ppt "C++ for Java-programmerere"

Liknende presentasjoner


Annonser fra Google