Formation C++. Hello World ! #include /* Commentaire sur plusieurs lignes */ int main() { //Affiche...

Preview:

Citation preview

Formation C++

Hello World !

#include <iostream>

/* Commentaire

sur plusieurs lignes */

int main()

{

//Affiche hello world

std::cout << "Hello World !“

<< std:endl;

}

Nouveautés de syntaxe en C++ Surcharge de fonctions, d’opérateurs Références

Namespace (non abordé) Fonctions templates (non abordé)

Surcharge de fonction

void f(int i) {}

int f(double i) {}

void f(int a,int b) {}

// ERREUR :

// Diffère uniquement par

// le type de retour

double f(int i) {}

Attention aux ambiguïtés

void f(int a, double b) {}void f(double a, int b) {}int a,b;f(a,b); // ??f((double)a,b); //ok

Le mieux est encore de ne pas écrire deux fonctions aux paramètres si proche l’un de l’autre !

Opérateurs

Mathématiques : +, -, *, /, %, ++, --

Logiques : &&, ||, !, ==, !=, <, >, <=, >=

Données : *, &, ->

Binaire : &, |, ^, ~, <<, >>

Assignation : =, *=, /=, %=, +=, -=, <<=, >>=, &=, |=, ^=

Tous surchargeables.

Références

Permettent de passer la variable plutôt que la copie.

Evite la recopie de la variable (gain en rapidité pour de grosses structures).

Permet de simplifier l’écritures de fonctions qui écrivent dans une variable.

Référence

void Double(int x)

{

x*=2;

}

int a=2;

Double(a); //a==2

void Double(int& x)

{ x*=2; }

Double(a); //a==4

void Double(int* x)

{ *x*=2; }

Double(&a); //a==4

Qu’est ce qu’un objet ?

Un type qui regroupe des informations (membres), et qui offre des moyens de les traiter (grâce à des méthodes).

Exemple : objet joueur

Membres :

points de vie

envie de manger

état (mort ?)

Méthodes :

Attaqué par

Mange

Comment définir un objet en C++class CJoueur

{

public:

void AttaqueDe(CJoueur& J)

{

Vie -= J.Vie; EnvieManger += 10;

Mort = ((Vie<=0)||(EnvieManger>=100));

}

void Mange() {EnvieManger=0;}

int Vie, EnvieManger; bool Mort;

};

Structure des fichiers d’un projet C++Header (.h)

Header (.h)

Code (.cpp)

Code (.cpp)

Objet (.o)

Objet (.o)

Executable

Compilation

Link

Les erreurs

Compilation Syntaxe (erreurs) Warnings

Linkage Fonctions et variables déclarées, non

implémentées Exécution

Segfault

Organisation des fichiers

Joueur.h :

class CJoueur

{

public:

void AttaqueDe(CJoueur& J);

void Mange();

int Vie, EnvieManger;

bool Mort;

};

Joueur.cpp :

void CJoueur::AttaqueDe(CJoueur& J)

{

Vie -= J.Vie;

EnvieManger += 10;

Mort = ((Vie<=0)||(EnvieManger>=100));

}

void CJoueur::Mange()

{ EnvieManger=0; }

Pré compilateur

Joueur.h :

#ifndef JOUEUR_H

#define JOUEUR_H

Class CJoueur

{/* … */ };

#endif

Joueur.cpp :

#include “Joueur.h”

void CJoueur::AttaqueDe(CJoueur& J)

Utilisation de l’objet

CJoueur J;

J.Mort=false;

J.Vie=100;

J.Mange();

CJoueur* p=&J;

(*p).Vie=100;

p->Vie=100;

p->Mange();

Constructeur – destructeur

Initialisation des données : on veut qu’à la création de la variable notre joueur soit vivant sans avoir besoin de le dire !

Constructeur : fonction appelée à la création de l’objet (pour l’initialisation)

Destructeur : fonction appelée à la destruction de l’objet

Constructeur – destructeur

class CJoueur

{

public:

CJoueur()

{

Vie=100; EnvieManger=0;

Mort=false;

}

~CJoueur() { }

};

new et delete, création dynamique d’objetsmalloc et free (du C) ne peuvent être utilisés car on a

besoin d’appeler le constructeur et le destructeur de l’objet

new T; retourne un pointeur vers une zone de donnée allouée par l’OS pour stocker un objet de type T.

delete p; informe l’OS que la mémoire préalablement allouée par un new n’est plus utile.

Toujours autant de new que de delete !

(règle sans aucune exception !)

Membres privés, publics

Cacher des membres et des propriétés à l’extérieur

Assurer que les données ne seront pas modifiées par l’extérieur

Indiquer à l’utilisateur les membres et méthodes dont il aura besoin

Conseil : mettre les membres en privé, avec au besoin des méthodes Get-Set

Membres privés, publicsclass CJoueur

{

public:

CJoueur();

~CJoueur();

void AttaqueDe(CJoueur& J);

void Mange();

bool IsDead();

private:

int Vie, EnvieManger;

bool Mort;

};

Dérivation

Créer un nouvel objet, plus spécifique, à partir d’un objet de base

CJoueur -> CJoueurHumain, CJoueurZerg, CJoueurProtoss

(CJoueur&)CJoueurHumain (CJoueurHumain&)CJoueur

Dérivation

class CJoueurZerg

: public CJoueur

{

public:

void SayGrrrgg();

};

CJoueurZerg Zergling;

CJoueur J;

Zergling.Mange();

J.AttaqueDe(Zergling);

Zergling.SayGrrrgg();

CJoueur* p=&Zergling;

p->SayGrrrgg(); //Error

Fonctions virtuelles

CJoueurHumain, CJoueurProtoss et CJoueurZerg ne mangent pas de la même façon. Pourtant on veut que tout CJoueur puisse manger.

Fonctions virtuelles

class CJoueur

{

public:

virtual void Mange()

{

EnvieManger=0;

}

};

class CJoueurZerg

:public CJoueur

{

public:

void Mange()

{

SayGrrrgg(); CJoueur::Mange();

}

};

Fonctions virtuelles

CJoueurZerg Over;

CJoueur J;

CJoueur* P=&Over;

J.Mange();

Over.Mange();

P->Mange();

Fonctions virtuelles pures

On ne sait pas définir CJoueur::Mange, on veut que les classes dérivées soient contraintes d’implémenter Mange()

class CJoueur

{

public:

virtual void Mange()=0;

};

Fonctions virtuelles pures

class CJoueurZerg

:public CJoueur

{

public:

void Mange()

{

SayGrrrgg(); EnvieManger=0;

}

};

CJoueurZerg Hydra;

Hydra.Mange();

CJoueur J; //Erreur

CJoueur* P=&Hydra;

P->Mange(); //OK

Fonctions virtuelles pures

class CJoueurHumain

:public CJoueur {};

class CCapitaine

:public CJoueurHumain

{

public:

void Mange()

{ /* … */ }

};

CJoueur J; //Erreur

CJoueurHumain J; //Erreur

CCapitaine Capitaine;

CJoueur* P=&Capitaine;

P->Mange(); //OK

class CMatrix {

public:

CMatrix() {}

CMatrix(const CMatrix& m);

double& operator()(int i,int j) {return Datas[i][j];}

CMatrix& operator=(CMatrix& m);

CMatrix& operator*=(double d);

CMatrix& operator+=(CNmatrix& m);

CMatrix operator+(CMatrix& m);

CMatrix operator-();

friend CMatrix operator*(double r,CMatrix& m);

private:

double Datas[3][3];

};

CMatrix::CMatrix(const CMatrix& m) { *this=m; }

CMatrix& CMatrix::operator=(CMatrix& m);

{

for(int i=0;i<3;++i)

for(int j=0;j<3;++j)

(*this)(i,j)=m(i,j);

return *this;

}

CMatrix& CMatrix::operator*=(double d)

{

for(int i=0;i<3;++i)

for(int j=0;j<3;++j)

(*this)(i,j)*=d;

return *this;

}

CMatrix CMatrix::operator*(double r,CMatrix& m)

{

CNmatrix R(m);

return R*=r;

}

CMatrix& CMatrix::operator+=(CNmatrix& m)

{

for(int i=0;i<3;++i)

for(int j=0;j<3;++j)

(*this)(i,j)+=m(i,j);

return *this;

}

CMatrix CMatrix::operator+(CMatrix& m)

{

CMatrix R(*this);

return R+=m;

}

CMatrix CMatrix::operator-() { return -1*(*this); }

Analyse d’une opération

CMatrix a,b,c;

//Initialisation de a et b…

c=2*a+b;

c.operator=(operator*(2,a).operator+(b));

CMatrix d=c;

CMatrix d(c);

La STL

Standard Template Library Bibliothèque standard (elle fait partie de la

norme C++) qui offre des types de variables et des fonctions utiles

Toutes les noms sont précédées de std::

std::string, std::vector, std::list, std::sort…

std::string (<string>)

Chaîne de caractères

std::string MonNom=“Vincent”;

MonNom.size()==7;

MonNom+=“ Lascaux”;

MonNom==“Vincent Lascaux”;

MonNom[0]==‘V’; MonNom[3]==‘c’;

std::vector (<vector>)

Container standard : tableau (acces rapide au n° élément (O(1)), insertion lente (O(n)) )

std::vector<int> Tableau;Tableau.resize(20);Tableau[0]=12; Tableau[1]=42;for(int i=2;i<20;i++) Tableau[i]=i*i;

Tableau.reserve(40);for(int i=0;i<20;++i)

Tableau.push_back(12);

std::list (<list>)

Une liste chaînée (acces lent au n° élément (O(n)), insertion rapide (O(1)) )

std::list<std::string> Liste;

Liste.push_back(“CNedra“);

Liste.push_back(“rulez”);

Liste.push_front(“See how “);

//Liste = [“See how”, “CNedra”, “rulez”]

Itérateurs

Permet de parcourir un container Unifie la syntaxe (tous les containers se

parcourent de la même façon, que ce soient tableau, liste, arbre ou autre)

S’utilise comme un pointeur (le container pointe sur un objet du container).

Itérateurs

int Somme=0;

for(std::vector<int>::iterator it=Tableau.begin(); it!=Tableau.end();it++)

Somme+=*it;

int Somme=0;

for(std::list<int>::iterator it=Liste.begin(); it!=Liste.end();it++)

Somme+=*it;

Les avantages de la STL

Ne pas réinventer la roue Eviter des bugs

(memory leaks… : la STL ne bug pas) Se simplifier la vie

Opérateurs usuels (=, ==, <, >…) Efficacité

D’écriture du code Du code

Tutoriaux

Thinking in C++ STL : aide de tout bon compilo,

tutoriaux sur le net, MSDN

Google est ton ami

Un peu de C

Les variables

int a;

int a,b;

int a=2;

int a=2, b=3;

int Puissance4(int x)

{

int carre;

carre=x*x;return carre*carre;

}

Quelques exemples

//Retourne le double de x

int Double(int x)

{

return 2*x;

}

Types entiers :

char, int, short, long

Types réels :

float, double

Evite d’utiliser le préfixe std:: avec la ligne

using namespace std;

#include <iostream>

int main()

{

std::cout << “Hello World\n”;

return 0;

}

Pointeurs

Un type de variable stockant l’adresse d’une zone en mémoire

Une valeur particulière : NULL

int a;

int* p;

p=&a;

*p=2; //a==2

a=3; //*p==3

Surtout utile pour les structures classiques (listes chaînées, arbres binaires…)

Contrôle du flux

Condition if – else Boucles do-while, while Boucle for

Condition

Le type d’une condition est bool, il peut prendre les valeurs true ou false. Les nombres entiers peuvent être testée :0 false, autre nombre true

<, <=, >, >=, ==, !=&&, ||, !

A==3 && B==2 A==((3 && B)==2) (A==3) && (B==2)

if - else

int sign(int x)

{

if(x<0)

{

return -1;

} else {

return 1;

}

}

int sign(int x)

{

if(x<0) return -1;

else return 1;

}

Boucles do-while et while

int Age;

do

{

cout<<"Quel est votre age ?“<<endl;

cin >> Age;

}while(Age<=0);

while(OnmEcoute())

{ Dit_un_mot(); }

Boucle for

int i;

for(i=0;i<10;i++)

{

cout << “10 fois”;

}

for(int i=0;i<10;i++)

cout << “10 fois”;

for(Init; Condition; Step) { Code }

Init; while(Condition) {Code; Step;}

Transtypage (cast)

Changer le type d’une expression

double a; (int)a;

int a; (double)a;

Transtypage implicite

double Carre(double a) {return a*a;}

Carre(2); //Carre((double)2), Carre(2.)

const

Problème des références : on ne sait plus si l’argument sera ou non modifié

const permet d’indiquer que l’argument ne pourra être modifié

Erreur à la compilation si une fonction modifie un argument const (par une affectation, ou l’appel d’une méthode non const)

Recommended