• Aucun résultat trouvé

Programmation par Objets en C++

N/A
N/A
Protected

Academic year: 2022

Partager "Programmation par Objets en C++"

Copied!
56
0
0

Texte intégral

(1)

Programmation par Objets en C++

Cl ´ement PERNET

L3-MI, UFR IM2AG, Universit ´e Grenoble Alpes

(2)

Plan du cours

H ´eritage (3-4)

(3)

Plan

H ´eritage (3-4)

Notion et r `egles de l’h ´eritage

Construction et initialisation des objets d ´eriv ´es H ´eritage et Polymorphisme

Red ´efinition statique et dynamique H ´eritage multiple

Les conversions

(4)

Plan

H ´eritage (3-4)

Notion et r `egles de l’h ´eritage

Construction et initialisation des objets d ´eriv ´es H ´eritage et Polymorphisme

Red ´efinition statique et dynamique H ´eritage multiple

Les conversions

(5)

H ´eritage

Structurer les concepts

I Un type de donn ´ee impl ´emente un concept (ex : un chat) I Il entretient des relations avec d’autre concepts :

I un chata4 pattes, 2 yeux, 2 oreilles, etc

I une chatestun f ´elin, un animal, quadrup `ede, etc

Faciliter la d ´efinition de nouvelles classes I Copier-coller de classes existantes I on ne d ´ecrit que ce qui change :

I nouveaux attributs I nouvelles m ´ethodes

I alt ´eration (re-d ´efinition) de certains membres

I Proc ´ed ´e it ´eratif : une classe d ´eriv ´ee peut servir de classe de base pour une nouvelle classe d ´eriv ´ee

(6)

H ´eritage

Structurer les concepts

I Un type de donn ´ee impl ´emente un concept (ex : un chat) I Il entretient des relations avec d’autre concepts :

I un chata4 pattes, 2 yeux, 2 oreilles, etc

I une chatestun f ´elin, un animal, quadrup `ede, etc

Faciliter la d ´efinition de nouvelles classes I Copier-coller de classes existantes I on ne d ´ecrit que ce qui change :

I nouveaux attributs I nouvelles m ´ethodes

I alt ´eration (re-d ´efinition) de certains membres

I Proc ´ed ´e it ´eratif : une classe d ´eriv ´ee peut servir de classe de base pour une nouvelle classe d ´eriv ´ee

(7)

H ´eritage

class Rectangle {

int _x, _y; // coordonn´ees du point inf. gauche int _h, _l; // hauteur et largeur

};

class RectangleColore : public Rectangle {

// les attributs _x,_y,_h,_l sont implicitement inclus Couleur _couleur;// ajout d’un attribut suppl´ementaire public:

// ajout d’une m´ethode suppl´ementaire

void changeCouleur (Couleur& coul){ _couleur = coul;}

};

(8)

H ´eritage et acc `es

La classe d ´eriv ´ee acc `ede toujours aux membrespublicet protectedde la classe de base. Si l’h ´eritage est

public : ces membres sont expos ´es avec le m ˆeme acc `es protected : ces membres sont expos ´es commeprotected

private : ces membres sontprivate

public

private protected

public

protected

private

Parent Type d’heritage Descendant

public

(9)

H ´eritage et acc `es

La classe d ´eriv ´ee acc `ede toujours aux membrespublicet protectedde la classe de base. Si l’h ´eritage est

public : ces membres sont expos ´es avec le m ˆeme acc `es protected : ces membres sont expos ´es commeprotected

private : ces membres sontprivate

public

private protected

public

protected

private

Parent Type d’heritage Descendant

public

(10)

H ´eritage et acc `es

La classe d ´eriv ´ee acc `ede toujours aux membrespublicet protectedde la classe de base. Si l’h ´eritage est

public : ces membres sont expos ´es avec le m ˆeme acc `es protected : ces membres sont expos ´es commeprotected

private : ces membres sontprivate

public

private protected

public

protected

private

Parent Type d’heritage Descendant

protected

(11)

H ´eritage et acc `es

La classe d ´eriv ´ee acc `ede toujours aux membrespublicet protectedde la classe de base. Si l’h ´eritage est

public : ces membres sont expos ´es avec le m ˆeme acc `es protected : ces membres sont expos ´es commeprotected

private : ces membres sontprivate

public

private protected

public

protected

private

Parent Type d’heritage Descendant

private

(12)

H ´eritage et acc `es

class A{

i n t a p r i v; protected:

i n t apro; p ub li c:

i n t apub; };

class B: p ub li c A{ };

class C: protected A{ }; class D: p r i v a t e A{ };

class E: p ub li c C{

void f( ){apub=1;} / / ok ; };

class F: p ub li c D{

void f( ){

/ / apub = 1 ; / / e r r e u r ; }

};

int main(){

A a; B b; C c; D d; E e; F f;

// a.apriv = 0; // erreur // a.apro = 0; // erreur

a.apub = 0; // ok b.apub = 0; // ok // c.apub = 0; // erreur // d.apub = 0; // erreur

}

(13)

Plan

H ´eritage (3-4)

Notion et r `egles de l’h ´eritage

Construction et initialisation des objets d ´eriv ´es H ´eritage et Polymorphisme

Red ´efinition statique et dynamique H ´eritage multiple

Les conversions

(14)

H ´eritage et constructeurs

I Les constructeursne sont pas h ´erit ´es

I Impossible d’initialiser les attributs de la classe de base I Possibilit ´e d’invoquer un constructeur de la classe de base

dans la classe d ´eriv ´ee

I C’est la seule fac¸on d’initialiser les attributs de la classe de base

class Rectangle {

int _x, _y; // coordonn´ees du point inf. gauche int _h, _l; // hauteur et largeur

public:

Rectangle(int x,int y,int h,int l): _x(x),_y(y),_h(h),_l(l){}

};

class RectangleColore : public Rectangle { Couleur _couleur;

public:

RectangleColore(int x, int y, int h, int l, Couleur& coul): Rectangle(x,y,h,l),

_couleur(coul){}

};

(15)

H ´eritage et constructeurs

I Les constructeursne sont pas h ´erit ´es

I Impossible d’initialiser les attributs de la classe de base I Possibilit ´e d’invoquer un constructeur de la classe de base

dans la classe d ´eriv ´ee

I C’est la seule fac¸on d’initialiser les attributs de la classe de

base

class Rectangle {

int _x, _y; // coordonn´ees du point inf. gauche int _h, _l; // hauteur et largeur

public:

Rectangle(int x,int y,int h,int l):

_x(x),_y(y),_h(h),_l(l){}

};

class RectangleColore : public Rectangle { Couleur _couleur;

public:

RectangleColore(int x, int y, int h, int l, Couleur& coul):

Rectangle(x,y,h,l), _couleur(coul){}

};

(16)

H ´eritage et constructeurs

Remarque

I Pas obligatoire de d ´efinir un constructeur (quand il n’y en a pas dans la classe de base)

I Si la classe de base a a un constructeur, alors obligation de l’appeler

I On ne peut invoquer que les constructeurs du parent imm ´ediat

Ordre de construction : 1. la classe parente

2. les membres de la d ´eriv ´ee 3. la classe d ´eriv ´ee elle-m ˆeme

(17)

H ´eritage et constructeurs

Remarque

I Pas obligatoire de d ´efinir un constructeur (quand il n’y en a pas dans la classe de base)

I Si la classe de base a a un constructeur, alors obligation de l’appeler

I On ne peut invoquer que les constructeurs du parent imm ´ediat

Ordre de construction : 1. la classe parente

2. les membres de la d ´eriv ´ee 3. la classe d ´eriv ´ee elle-m ˆeme

(18)

Plan

H ´eritage (3-4)

Notion et r `egles de l’h ´eritage

Construction et initialisation des objets d ´eriv ´es H ´eritage et Polymorphisme

Red ´efinition statique et dynamique H ´eritage multiple

Les conversions

(19)

H ´eritage et Polymorphisme

Polymorphisme : faire passer un objet d’un type pour un objet d’un autre type.

Solution de l’h ´eritage

Si ce n’est toi c’est donc ton p `ere Un descendant a toutes les propri ´et ´es d’un parent. Permet de :

I faire op ´erer une m ˆeme fonction sur des donn ´ees de types diff ´erents (mais qui ont en commun ce que demande la fonction)

I faire des collections d’objets de types diff ´erents, ayant un anc ˆetre commun

(20)

H ´eritage et Polymorphisme

Polymorphisme : faire passer un objet d’un type pour un objet d’un autre type.

Solution de l’h ´eritage

Si ce n’est toi c’est donc ton p `ere Un descendant a toutes les propri ´et ´es d’un parent.

Permet de :

I faire op ´erer une m ˆeme fonction sur des donn ´ees de types diff ´erents (mais qui ont en commun ce que demande la fonction)

I faire des collections d’objets de types diff ´erents, ayant un anc ˆetre commun

(21)

H ´eritage et polymorphisme

Exemple :

struct Article{

int prix;

};

struct Livre: public Article{

std::string titre;

};

struct DVD: public Article{

int duree;

};

void facture (std::vector<Article>& v){

int total = 0;

for (auto x:v) total += x.prix;

}

(22)

Limitation

Risque de perte d’information :

struct Article{

void affiche(){std::cout<<"un Article"<<std::endl;}

};

struct Livre: public Article{

void affiche(){std::cout<<"un Livre"<<std::endl;}

};

struct DVD: public Article{

void affiche(){std::cout<<"un DVD"<<std::endl;}

};

void presenter(Article& a){ // polymorphisme std::cout<<"Je suis ";

a.affiche();

}

int main(){

DVD Tenet;

Livre VernonSubutex;

presenter (Tenet); // -> Je suis un Article presenter (VernonSubutex); // -> Je suis un Article

}

(23)

Plan

H ´eritage (3-4)

Notion et r `egles de l’h ´eritage

Construction et initialisation des objets d ´eriv ´es H ´eritage et Polymorphisme

Red ´efinition statique et dynamique H ´eritage multiple

Les conversions

(24)

H ´eritage et red ´efinition de m ´ethodes

I Par d ´efaut les m ´ethodespublicetprotectedde la classe de base sont h ´erit ´ees

I Si on veut les modifier dans la classe d ´eriv ´ee, il faut les red ´efinir.

Red ´efinition statique : r ´esolution statique `a la compilation en cas de polymorphisme (cf ex des DVD/Livres)

Le compilateur choisit la m ´ethode d’apr `es le type

Red ´efinition dynamique : r ´esolution dynamique en cas de polymorphisme

le type effectif de l’objet `a l’ex ´ecution d ´eterminera quelle m ´ethode sera appel ´ee

(25)

H ´eritage et red ´efinition de m ´ethodes

I Par d ´efaut les m ´ethodespublicetprotectedde la classe de base sont h ´erit ´ees

I Si on veut les modifier dans la classe d ´eriv ´ee, il faut les red ´efinir.

Red ´efinition statique : r ´esolution statique `a la compilation en cas de polymorphisme (cf ex des DVD/Livres)

Le compilateur choisit la m ´ethode d’apr `es le type

Red ´efinition dynamique : r ´esolution dynamique en cas de polymorphisme

le type effectif de l’objet `a l’ex ´ecution d ´eterminera quelle m ´ethode sera appel ´ee

(26)

H ´eritage et red ´efinition de m ´ethodes

I Par d ´efaut les m ´ethodespublicetprotectedde la classe de base sont h ´erit ´ees

I Si on veut les modifier dans la classe d ´eriv ´ee, il faut les red ´efinir.

Red ´efinition statique : r ´esolution statique `a la compilation en cas de polymorphisme (cf ex des DVD/Livres)

Le compilateur choisit la m ´ethode d’apr `es le type

Red ´efinition dynamique : r ´esolution dynamique en cas de polymorphisme

le type effectif de l’objet `a l’ex ´ecution d ´eterminera quelle m ´ethode sera appel ´ee

(27)

Red ´efinition de m ´ethodes et d ´erivations successives

A*

B

D* E

C*

F

X* signifie une d ´efinition ou red ´efinition d’une m ´ethodef classe A : m ´ethodefde A

classe B : m ´ethodefde A classe C : m ´ethodefde C classe D : m ´ethodefde D classe E : m ´ethodefde A classe F : m ´ethodefde C

(28)

Red ´efinition statique et dynamique

Red ´efinition statique

Simplement en d ´efinissant `a nouveau (avec la m ˆeme signature) :

struct Article{

void affiche(){std::cout<<"un Article"<<std::endl;}

};

struct Livre: public Article{

void affiche(){std::cout<<"un Livre"<<std::endl;}

};

void presenter(Article& a){ // polymorphisme std::cout<<"Je suis ";

a.affiche(); // r´esolution statique: affiche de Article }

int main(){

Livre VernonSubutex;

presenter (VernonSubutex); // -> Je suis un Article

}

(29)

Red ´efinition statique et dynamique

Red ´efinition dynamique

Pour permettre la red ´efinition avec r ´esolution dynamique il faut I l’attributvirtual `a la m ´ethode de la classe de base I utiliser un passage par pointeur ou r ´ef ´erence

struct Article{

virtual void affiche(){std::cout<<"un Article"<<std::endl;}

};

struct Livre: public Article{

void affiche() {std::cout<<"un Livre"<<std::endl;}

};

struct DVD: public Article{

void affiche() {std::cout<<"un DVD"<<std::endl;}

};

void presenter(Article& a){ // polymorphisme std::cout<<"Je suis "; a.affiche();}

int main(){

DVD Tenet; Livre VernonSubutex;

presenter (Tenet); // -> Je suis un DVD presenter (VernonSubutex); // -> Je suis un Livre

}

(30)

Organisation des m ´ethodes red ´efinies dynamiquement

I Dans la classe debase, la m ´ethode doit ˆetrevirtual I Dans la classed ´eriv ´ee, la m ´ethode peut ˆetreoverride

(C++11)

d ´eclare l’intention de red ´efinir, pour ´eviter les bugs : I oubli devirtualdans la classe de base

I signatures diff ´erentes

I Pour interdire de red ´efinir dans une classe d ´eriv ´ee de la d ´eriv ´ee :final(C++11)

(31)

H ´eritage, red ´efinition et override : illustration

struct Article{

virtual void affiche(){

std::cout<<"un Article"<<std::endl;}

};

struct Livre: public Article{

void affiche() override {

std::cout<<"un Livre"<<std::endl;}

};

struct DVD: public Article{

void affiche() { // override est facultatif std::cout<<"un DVD"<<std::endl;}

};

void presenter(Article& a){ // polymorphisme std::cout<<"Je suis ";

a.affiche();

}

int main(){

DVD Tenet;

Livre VernonSubutex;

presenter (Tenet); // -> Je suis un DVD presenter (VernonSubutex); // -> Je suis un Livre

}

(32)

H ´eritage, red ´efinition et override : illustration

struct Article{

void affiche(){

std::cout<<"un Article"<<std::endl;}

};

struct Livre: public Article{

void affiche() override { //erreur, parent pas virtual std::cout<<"un Livre"<<std::endl;}

};

struct DVD: public Article{

void affiche() override { //erreur, parent pas virtual std::cout<<"un DVD"<<std::endl;}

};

void presenter(Article& a){ // polymorphisme std::cout<<"Je suis ";

a.affiche();

}

int main(){

DVD Tenet;

Livre VernonSubutex;

presenter (Tenet); // -> Je suis un DVD presenter (VernonSubutex); // -> Je suis un Livre

}

(33)

H ´eritage, red ´efinition et override : illustration

struct Article{

virtual void affiche(){

std::cout<<"un Article"<<std::endl;}

};

struct Livre: public Article{

void affiche() const override{ //erreur, signatures !=

std::cout<<"un Livre"<<std::endl;}

};

struct DVD: public Article{

void affiche() final { // ne pourra ˆetre red´efinie plus bas std::cout<<"un DVD"<<std::endl;}

};

void presenter(Article& a){ // polymorphisme std::cout<<"Je suis ";

a.affiche();

}

int main(){

DVD Tenet;

Livre VernonSubutex;

presenter (Tenet); // -> Je suis un DVD presenter (VernonSubutex); // -> Je suis un Livre

}

(34)

H ´eritage, red ´efinition et override : illustration

struct A{

int zero(){return 0;}

virtual int un(){return 1;}

};

struct B: public A{

int zero (){return 1;};

int un (){return 0;};

};

int main(){

A a; B b;

A& ref_a = a;

ref_a.zero(); // retourne 0;

ref_a.un(); // retourne 1;

A* ptr_a = &b // un B passe pour un A

//(possible car h´eritage public)

ptr_a->zero();// retourne 0 car ptr_a pointe vers un A // et zero n’est pas virtual

ptr_a->un(); // retourne 0 car la fct est virtual ptr_a = &a;

ptr_a->zero();// retourne 0 ptr_a->un(); // retourne 1

}

(35)

R ´esolution dynamique : comment c¸a marche

Chaque classe abstraite (contenant des m ´ethodes virtuelles) : I poss `ede unevtable: un tableau de pointeurs vers ses

m ´ethodes

Chaque objet instance de cette classe

I poss `ede un pointeurvpointervers la vtable de sa classe garde l’information m ˆeme lorsque l’objet est pris pour son parent

struct A{

int x;

virtual int zero(){return 0;}

virtual int un(){return 1;}

};

struct B: public A{

int y;

int un() override{return 0;};

};

vtable de A

zero() un()

A::zero() A::un() B::un() vtable de B

zero() un()

(36)

R ´esolution dynamique : comment c¸a marche

Chaque classe abstraite (contenant des m ´ethodes virtuelles) : I poss `ede unevtable: un tableau de pointeurs vers ses

m ´ethodes

Chaque objet instance de cette classe

I poss `ede un pointeurvpointervers la vtable de sa classe garde l’information m ˆeme lorsque l’objet est pris pour son parent

struct A{

int x;

virtual int zero(){return 0;}

virtual int un(){return 1;}

};

struct B: public A{

int y;

int un() override{return 0;};

};

vtable de A zero() un()

A::zero() A::un() B::un() vtable de B

zero() un() Objet a

vptr x Objet b

vptr x y

(37)

M ´ethodes virtuelles pures

Une m ´ethode peut ˆetre virtuelle pure :

class FormeGeometrique{

public:

virtual double aire () = 0;

};

I pas d’impl ´ementation propos ´ee dans cette classe I donc impossible d’instancier des objets de cette classe I uniquement utilis ´ee comme classe de base, dont les

d ´eriv ´ees impl ´ementent les m ´ethodes virtuelles pures la classe est diteabstraite

I une classe dont toutes les m ´ethodes sont abstraites est uneinterface

(38)

Plan

H ´eritage (3-4)

Notion et r `egles de l’h ´eritage

Construction et initialisation des objets d ´eriv ´es H ´eritage et Polymorphisme

Red ´efinition statique et dynamique H ´eritage multiple

Les conversions

(39)

H ´eritage multiple

EnC++, une classe peut h ´eriter de plusieurs classes

(pas en Java, ou de fac¸on limit ´ee via les interfaces).

class Telephone{

public:

virtual void composer(char* numero) = 0;

};

class Tablette{

public:

virtual void lancerNavigateur () = 0;

};

class SmartPhone : public Telephone, public Tablette{

void composer (char* numero) override {...}

void lancerNavigateur () override {...}

};

I Les membres de chaque classe de base sont h ´erit ´es dans la classe d ´eriv ´ee

I Et en cas de conflit ?

(40)

H ´eritage multiple

Si les classes de base ont des membres ayant le m ˆeme nom : I n’emp ˆeche pas l’h ´eritage multiple

I oblige de lever l’ambiguit ´e `a l’utilisation

I bonne pratique : red ´efinir pour lever l’ambiguit ´e une fois pour toute

struct Telephone{

void composer(char* numero);

void start();

};

struct Tablette{

void lancerNavigateur ();

void start();

};

class SmartPhone : public Telephone, public Tablette{ };

void f(SmartPhone* sp){

sp->start(); // ambigu sp->Tablette::start(); // OK sp->Telephone::start(); // OK

}

(41)

H ´eritage multiple

Si les classes de base ont des membres ayant le m ˆeme nom : I n’emp ˆeche pas l’h ´eritage multiple

I oblige de lever l’ambiguit ´e `a l’utilisation

I bonne pratique : red ´efinir pour lever l’ambiguit ´e une fois pour toute

struct Telephone{

void composer(char* numero);

virtual void start();

};

struct Tablette{

void lancerNavigateur ();

virtual void start();

};

class SmartPhone : public Telephone, public Tablette{

void start() override { Telephone::start();

Tablette::start();

...;

} };

void f(SmartPhone* sp){

sp->start(); // OK

}

(42)

H ´eritage multiple avec anc ˆetre r ´ep ´et ´e

Tablette

SmartPhone Telephone

AppareilElec AppareilElec

struct AppareilElec{ bool _on;

};

struct Telephone : public AppareilElec{...}; struct Tablette : public AppareilElec{...};

class SmartPhone : public Telephone, public Tablette{ void start() override{

_on = true; // erreur ambigu

AppareilElec::_on = true; // erreur ambigu Telephone::AppareilElec::_on = true; // ok

Tablette::AppareilElec::_on = true; // ok aussi

};

I 2 instances de la classe de base sont pr ´esentes I peut ˆetre justifi ´e par l’application

(43)

H ´eritage multiple avec anc ˆetre r ´ep ´et ´e

Tablette

SmartPhone Telephone

AppareilElec AppareilElec

struct AppareilElec{

bool _on;

};

struct Telephone : public AppareilElec{...};

struct Tablette : public AppareilElec{...};

class SmartPhone : public Telephone, public Tablette{

void start() override{

_on = true; // erreur ambigu

AppareilElec::_on = true; // erreur ambigu Telephone::AppareilElec::_on = true; // ok

Tablette::AppareilElec::_on = true; // ok aussi

};

I 2 instances de la classe de base sont pr ´esentes I peut ˆetre justifi ´e par l’application

(44)

H ´eritage multiple avec anc ˆetre commun

Tablette

SmartPhone Telephone

AppareilElec

Classes de bases virtuelles :class T : public virtual X ...

struct AppareilElec{ bool _on;

};

struct Telephone : public virtual AppareilElec{...}; struct Tablette : public virtual AppareilElec{...}; class SmartPhone : public Telephone, public Tablette{

void start() override{

_on = true; // ok

};

I 1 unique instance de la classe de base virtuelle pr ´esente I son constructeur n’est appel ´e qu’une fois.

(45)

H ´eritage multiple avec anc ˆetre commun

Tablette

SmartPhone Telephone

AppareilElec

Classes de bases virtuelles :class T : public virtual X ...

struct AppareilElec{

bool _on;

};

struct Telephone : public virtual AppareilElec{...};

struct Tablette : public virtual AppareilElec{...};

class SmartPhone : public Telephone, public Tablette{

void start() override{

_on = true; // ok

};

I 1 unique instance de la classe de base virtuelle pr ´esente I son constructeur n’est appel ´e qu’une fois.

(46)

Plan

H ´eritage (3-4)

Notion et r `egles de l’h ´eritage

Construction et initialisation des objets d ´eriv ´es H ´eritage et Polymorphisme

Red ´efinition statique et dynamique H ´eritage multiple

Les conversions

(47)

Les conversions implicites

int x=1;

long y = (long) x; //promotion long z = long(x);

float t = (float) x;

A* a = new B; // up-cast implicite valide

(48)

Conversion entre classes

Au dela de la conversionup-cast via h ´eritage, d ´ej `a vue, on peut impl ´ementer des conversions de toute classe vers une autre :

I par un constructeur :

class Entier;

class Rationnel{

Entier num, den;

public:

// Conversion d’un Entier vers un Rationnel Rationnel(Entier& n):num(n),den(1){}

};

int main(){

Entier n(1);

Rationnel r(n);

}

(49)

Conversion entre classes

I par un op ´erateur de conversion

class Rationnel{

int num, den;

public:

Rationnel(int n, int d):num(n),den(d){}

};

class Entier{

int val;

public:

Entier(int n):val(n){}

operator int(){return val;}

operator Rationnel(){return Rationnel(*this,1);}

};

int main(){

Entier n(1);

Rationnel r(n);

}

(50)

Conversion dynamique

dynamic_cast<Type>

I Utilisable uniquement sur des ptrs ou ref vers des classes

I Permet de convertir vers un typecomplet `a l’ex ´ecution I Up-cast : D ´eriv ´eeBase

I Down-cast : BaseD ´eriv ´ee I En cas d’ ´echec :

I si pointeur : retournenullptr

I si r ´ef ´erence : l `eve l’exceptionstd::bad_cast

class A{};

class B : public A{int n;};

int main(){ A* pa = new A; A* pb = new B; B* b;

b = dynamic_cast<B*> (pb); // OK car le type effectif de pb est B*

b = dynamic_cast<B*> (pa); // KO retourne nullptr

}

(51)

Conversion dynamique

dynamic_cast<Type>

I Utilisable uniquement sur des ptrs ou ref vers des classes I Permet de convertir vers un typecomplet `a l’ex ´ecution

I Up-cast : D ´eriv ´eeBase I Down-cast : BaseD ´eriv ´ee

I En cas d’ ´echec :

I si pointeur : retournenullptr

I si r ´ef ´erence : l `eve l’exceptionstd::bad_cast

class A{};

class B : public A{int n;};

int main(){

A* pa = new A;

A* pb = new B;

B* b;

b = dynamic_cast<B*> (pb); // OK car le type effectif de pb est B*

b = dynamic_cast<B*> (pa); // KO retourne nullptr

}

(52)

Conversion dynamique

dynamic_cast<Type>

I Utilisable uniquement sur des ptrs ou ref vers des classes I Permet de convertir vers un typecomplet `a l’ex ´ecution

I Up-cast : D ´eriv ´eeBase I Down-cast : BaseD ´eriv ´ee I En cas d’ ´echec :

I si pointeur : retournenullptr

I si r ´ef ´erence : l `eve l’exceptionstd::bad_cast

class A{};

class B : public A{int n;};

int main(){

A* pa = new A;

A* pb = new B;

B* b;

b = dynamic_cast<B*> (pb); // OK car le type effectif de pb est B*

b = dynamic_cast<B*> (pa); // KO retourne nullptr

}

(53)

Conversion statique

static_cast<Type>

I Commedynamic_cast: up-castetdown-cast pour des ptr ou ref de classes

I Attention : pas de v ´erification dynamique avec lev ´ee de std::bad_castounullptr: au programmeur de s’assurer que c¸a marche

I mais pas de surco ˆut pour la v ´erification des types I appel explicite `a une conversion (constructeur `a 1

argument, op ´erateur de conversion, ...)

I convertit des types de base entre eux (promotion ou forc ´ee)

class A{};

class B : public A{int n;}; int main(){

A* pa = new A; A* pb = new B; B* b;

b = static_cast<B*>(pb);//OK car le type effectif de pb est B* b = static_cast<B*>(pa);//compile, mais runtime error

(54)

Conversion statique

static_cast<Type>

I Commedynamic_cast: up-castetdown-cast pour des ptr ou ref de classes

I Attention : pas de v ´erification dynamique avec lev ´ee de std::bad_castounullptr: au programmeur de s’assurer que c¸a marche

I mais pas de surco ˆut pour la v ´erification des types I appel explicite `a une conversion (constructeur `a 1

argument, op ´erateur de conversion, ...)

I convertit des types de base entre eux (promotion ou forc ´ee)

class A{};

class B : public A{int n;};

int main(){

A* pa = new A;

A* pb = new B;

B* b;

b = static_cast<B*>(pb);//OK car le type effectif de pb est B*

b = static_cast<B*>(pa);//compile, mais runtime error

(55)

Conversion de constance

const_cast<Type>.

S’applique dans les 2 sens :

I pour enlever la constanceconst_cast<T> (x)

I pour ajouter la constanceconst_cast<const T> (y)

bool estEntier (const Rationnel& cr){

const_cast<Rationnel>(cr) . simplifie(); // modifie l’objet r return r._den == 1;

}

(56)

Conversion de constance

const_cast<Type>.

S’applique dans les 2 sens :

I pour enlever la constanceconst_cast<T> (x)

I pour ajouter la constanceconst_cast<const T> (y)

bool estEntier (const Rationnel& cr){

const_cast<Rationnel>(cr) . simplifie(); // modifie l’objet r return r._den == 1;

}

Références

Documents relatifs

class Button { private string Nom=””; public string Name() { get { return Nom;} set { if ( value != null ) Nom = value; } } Utilisation : Button X = new Button(); X.Name

[r]

[r]

http://projet.eu.org/pedago/sin/1ere/ds/ds5_numeration_correction.pdf à préparer : contrôle numération pour semaine prochaine (mardi) 6 21/09/15 présentation avant projet (étude

20 21/11 FLOT logique combinatoire : http://projet.eu.org/pedago/sin/mooc/mooc6.zip à préparer DS : transmission de données. chaine I/E, CAN/CNA, transmission

http://projet.eu.org/pedago/sin/mooc/mooc10.zip ex 4 et 5 : loi de Pouillet à rendre sur dropbox à préparer : FLOT la Machine à Courant

à préparer : DS FLOT la Machine à Courant Continu 52 20/05 FLOT le hacheur série. http://projet.eu.org/pedago/sin/mooc/mooc12.zip 53 24/05 DS FLOT la Machine à

à préparer pour semaine prochaine (lundi) : contrôle (exercices) 5 24/09/15 prise en main de