Cours c++

Ce cours suppose le langage C connu.

On trouvera le listing du corrigé des exercices à la fin de chaque chapitre.
Une disquette, contenant le programme source de ces exercices est fournie avec le polycopié.
Ces programmes ont été mis au point sous environnement BORLAND C++ sous WINDOWS.

Pour avancer un peu plus vite et aborder l'essentiel de la Programmation Orientée Objet (P.O.O.), on pourra étudier les chapitres et paragraphes marqués de ***, dans un deuxième temps.

CHAPITRE 1, INCOMPATIBILITES ENTRE C ET C++, NOUVELLES POSSIBILITES DU C++

Dans ce premier chapitre sont exposés les «plus» et les différences du C++ par rapport au C, sans toutefois aborder la programmation orientée objet (P.O.O.) qui sera vue lors d'un prochain chapitre.

I- COMMENTAIRES
En C++, les commentaires s'écrivent derrière un // et se terminent avec la fin de la ligne.
Exemple:

void main()     // ceci est un commentaire
{                      // noter que le qualificatif «void» est obligatoire 
  int n =2;           // devant «main()»
}

II- LE QUALIFICATIF « CONST »
En C++, de telles déclarations de tableaux sont autorisées:

const int taille =  5;
char tab1[taille] ;
float tab2[taille + 1] [taille *2];

III- DECLARATION DES VARIABLES
En C++, on peut déclarer les variables LOCALES au moment où on en a besoin. Si une variable locale est déclarée au début d'un bloc, sa portée est limitée à ce bloc.
Exemple:

void main()
{
  for ( int i  = 0;i<10;i++ )         // la variable i est connue de toute la fonction
  {                                   // «main()»
    int j;                            // la variable j n'est connue que du bloc
    ...;                               
    ...;
  }
}

Cet exemple est équivalent à:

void main()
{
  int i;
  for ( i =  0;i<10;i++ )   // la variable i est connue de toute la fonction                                  
  {                                  // « main() »
    int j;                // la variable j n'est connue que du bloc
    ...;                               
    ...;
  }
}

Cette possibilité autorise une gestion plus précise de la mémoire, mais peut nuire à la structuration des programmes.

IV- LES NOUVELLES POSSIBILITES D'ENTREES/SORTIES
On peut utiliser en C++ les fonctions d'entrées/sorties classiques du C (printf, scanf, puts, gets, putc, getc ...), à condition de déclarer le fichier d'en-tête stdio.h.

Il existe de nouvelles possibilités en C++, à condition de déclarer le fichier d'en-tête iostream.h .

Ces nouvelles possibilités ne nécessitent pas de FORMATAGE des données.

Sortie sur écran: l'opérateur cout
Exemples:

cout << "BONJOUR";        // équivalent à   puts("BONJOUR");
int n = 25;
cout << "Valeur: ";            // équivalent à   puts("Valeur");
cout << n;                         // équivalent à   printf("%d",n);

// On peut encore écrire directement:
cout <<"Valeur:" << n;

cout <<"\n ";                     // pour aller à la ligne
char c =   `a';                           
cout << c;                        // affiche le caractère, il faut utiliser
                                       // printf (formatage), pour obtenir le code ASCII

Cette dernière notation sera justifiée lors du chapitre sur les flots.

L'opérateur cout permet d'afficher des nombres entiers ou réels, des caractères, des chaînes de caractères, des pointeurs autre que de type *char (valeur de l'adresse).

Exemple (à tester) et exercice I-1:

#include 
#include <conio.h>

void main()       
{
  int i,n  =25,*p;
  char *tc=  "On essaie cout !";
  float x = 123.456;
  cout<<"BONJOUR\n";
  cout<<tc<<"\n";
  cout<<"BONJOUR\n"<<tc<<"\n";
  cout<<"n= "<<n<<"  x= "<<x<<"  p=  "<
  getch() ;
}

Saisie clavier: l'opérateur cin
Exemples:

int n;
cout<<"Saisir un entier:  ";
cin >> n;                     // équivalent à scanf("%d",&n);

int a, b;
cin >> a >> b;            // saisie de 2 entiers séparés par un Retour Chariot

Cette dernière notation sera justifiée lors du chapitre sur les flots.

L'opérateur cinpermet de saisir des nombres entiers ou réels, des caractères, des chaînes de caractères.

Exemple (à tester) et exercice I-2:
Tester cet exemple plusieurs fois, notamment en effectuant des saisies erronées de sorte d'évaluer les « anomalies » de fonctionnement de cin.

#include 
#include <conio.h>

void main()
{
  int n;
  char tc[30 * ,c;
  float x;
  cout<<"Saisir un entier:";
  cin>>n;
  cout<<"Saisir un réel:";
  cin>>x;
  cout<<"Saisir une phrase:";
  cin>>tc;
  cout<<"Saisir une lettre:";
  cin>>c;
  cout<<"Relecture: "<<n<<" "<<x<<" "<<tc<<" "<<c<<"\n";
  getch() ;
}

V- LES CONVERSIONS DE TYPE
Le langage C++ autorise les conversions de type entre variables de type char, int, float, double.
Exemple:

void main()
{
  char c =0x56, d = 25,e;
  int i=0x1234,j;
  float r=678.9,s;
  j = c;                           // j vaut 0x0056 
  j = r;                           // j vaut 678 
  s = d;                          // s vaut 25.0 
  e =  i;                           // e vaut 0x34 
}

Une conversion de type float --> int ou char est dite dégradante

Une conversion de type int ou char --> float est dite non dégradante

VI- LES CONVERSIONS DE TYPE LORS D'APPEL A FONCTION
Le C++, contrairement au C, autorise, dans une certaine mesure, le non-respect du type des arguments lors d'un appel à fonction: le compilateur opère alors une conversion de type.
Exemple:

double ma_fonction(int u, float f)
{
  ....;                                      // fonction avec passage de deux paramètres
  .....;
}

void main()
{
  char c; int i, j; float r; double r1, r2, r3, r4;
  r1 = ma_fonction( i, r );   // appel standard
  r2 = ma_fonction( c, r);   // appel correct,  c est converti en int 
  r3 = ma_fonction( i, j);    // appel correct, j est converti en float
  r4 = ma_fonction( r, j);   // appel correct, r est converti en int
                                        // et  j est converti en float 
}

Exercice I-3
Ecrire une fonction float puissance(float x,int n) qui renvoie xn. La mettre en oeuvre en utilisant les propriétés de conversion de type.

VII- LES ARGUMENTS PAR DEFAUT
En C++, on peut préciser la valeur prise par défaut par un argument de fonction. Lors de l'appel à cette fonction, si on omet l'argument, il prendra la valeur indiquée par défaut, dans le cas contraire, cette valeur par défaut est ignorée.
Exemple:

void f1(int n   =  3)  // par défaut le paramètre n vaut 3
{
  ...;
}     

void f2(int n, float x  =  2.35)  // par défaut le paramètre x vaut 2.35
{
  ...;
}

void f3(char c, int n = 3, float x = 2.35)  // par défaut le paramètre n vaut 3
{                                                            // et le paramètre x vaut 2.35
  ...;
}

void main()
{
  char a = 0;
  int i = 2;
  float r = 5.6;

  f1(i);                        // l'argument n vaut 2, l'initialisation par défaut est ignorée
  f1();                        // l'argument n prend la valeur par défaut
  
  f2(i,r);                      // les initialisations par défaut sont ignorées
  f2(i);                        //  le second paramètre prend la valeur par défaut
  // f2();  interdit

  f3(a, i, r);                //  les initialisations par défaut sont ignorées
  f3(a, i);                    //  le troisième paramètre prend la valeur par défaut
  f3(a);                       //  le deuxième et la troisième paramètres prennent les valeurs                          
                                 //  par défaut

Remarque:
Les arguments, dont la valeur est fournie par défaut, doivent OBLIGATOIREMENT se situer en fin de liste.
La déclaration suivante est interdite:

void f4(char c =2, int n)
{
  ...;
}

Exercice I-4
Reprendre l'exercice précédent. Par défaut, la fonction puissance devra fournir x4.

VIII- LA SURDEFINITION DES FONCTIONS
Le C++ autorise la définition de fonctions différentes et portant le même nom. Dans ce cas, il faut les différencier par le type des arguments.

Exemple (à tester) et exercice I-5:

#include 
#include <conio.h>
void test(int n  = 0,float x = 2.5) 
{
  cout <<"Fonction N°1 :  ";
  cout << "n= "<<n<<"  x="<<x<<"\n";
}

void test(float x = 4.1,int n = 2)
{
  cout <<"Fonction N°2 :  ";
  cout << "n= "<<n<<"  x="<<x<<"\n";
}

void main()
{
  int i = 5; float r = 3.2;
  test(i,r);          // fonction N°1
  test(r,i);          // fonction N°2
  test(i);             // fonction N°1
  test(r);            // fonction N°2
  
  // les appels suivants, ambigüs, sont rejetés par le compilateur
  // test();
  // test (i,i);
  // test (r,r);

  // les initialisations par défaut de x à la valeur 4.1
  // et de n à 0 sont inutilisables 

  getch() ;
}     

Exemple (à tester) et exercice I-6:

#include 
#include <conio.h>

void essai(float x,char c,int n =0)
{
  cout<<"Fonction N°1: x =  "<<x<<" c = "<<c<<" n = "<<n<<"\n";
}

void essai(float x,int n)
{
  cout<<"Fonction N°2: x = "<<x<<" n = "<<n<<"\n";
}

void main()
{
  char l='z';int u=4;float y = 2.0;
  
  essai(y,l,u);    // fonction N°1
  essai(y,l);       // fonction N°1
  essai(y,u);      // fonction N°2
  essai(u,u);      // fonction N°2
  essai(u,l);       // fonction N°1
  // essai(y,y); rejet par le complateur
  essai(y,y,u);   // fonction N°1
  
  getch() ;
}

Exercice I-7:
Ecrire une fonction void affiche (float x, int n = 0) qui affiche xn (avec en particulier x0 = 1 et donc, 00 = 1).

Ecrire une autre fonction void affiche(int n, float x =0) qui affiche xn (avec en particulier 0n = 0 et donc, 00 = 0).

Les mettre en oeuvre dans le programme principal, en utilisant la propriété de surdéfinition.

Remarque: Cet exemple conduit à une erreur de compilation lors d'appel de type mn avec m et n entiers.

IX- LES OPERATEURS new ET delete
Ces deux opérateurs remplacent malloc et free (que l'on peut toujours utiliser). Ils permettent donc de réserver de la place en mémoire, et d'en libérer.

Exemples:

int *ad;                   // déclaration d'un pointeur sur un entier
ad   = new int;        // réservation de place en mémoire pour un entier
// On aurait pu déclarer directement: int *ad  =  new int;

char *adc;
adc =  new char[100] ;   // réservation de place en mémoire pour 100 caractères
// On aurait pu déclarer directement: char *adc = new char[100] ;

int *adi;
adi = new int[40] ;          // réservation de place en mémoire pour 40 entiers
// On aurait pu déclarer directement : int *adi  = new int[40 * ;

delete ad;               // libération de place
delete adc;
delete adi;

Exemple (à tester) et exercice I-8:

#include    // new et delete
#include <conio.h>      // verifier en testant que cin et cout posent les
                                   // memes pb que scanf et printf (flux d'E-S)
void main()
{
  int *ad =  new int;
  char *adc;
  adc =  new char[25] ;
   
  cout<<"Entrer un nombre:";
  cin>>*ad;
  cout<<"Voici ce nombre:"<<*ad;

  cout<<"\nEntrer une phrase:";
  cin>>adc;
  cout<<"Voici cette phrase:"<<adc;

  delete ad;
  delete adc;

  getch() ;
}

Exercice I-9:
Déclarer un tableau de 5 réels. Calculer et afficher leur moyenne.
Remarques:
- Il ne faut pas utiliser conjointement malloc et delete ou bien new et free.
- En TURBO C++, l'opérateur new permet de réserver au maximum 64 Koctets en mémoire; la fonction set_new_handler permet de gérer cette limite.

X- NOTION DE REFERENCE
En C, la notation &n signifie « l'adresse de la variable n »
En C++, cette notation possède deux significations:
- Il peut toujours s'agir de l'adresse de la variable n
- Il peut aussi s'agir de la référence à n

Seul le contexte du programme permet de déterminer s'il s'agit de l'une ou l'autre des deux significations.

Exemple:

int n;
int &p = n;               // p est une référence à n
                               // p occupe le même emplacement mémoire que n
n  =  3;
cout<< p;                // l'affichage donnera 3

XI -PASSAGE DE PARAMETRE PAR REFERENCE
Rappel:
En C, comme en C++, un sous-programme ne peut modifier la valeur d'une variable locale passée en argument de fonction. Pour se faire, en C, il faut passer l'adresse de la variable.

Exemple (à tester) et exercices I-10 et I-11:

#include  //    passage par valeur
#include <conio.h>

void echange(int a,int b)
{
  int tampon;
  tampon  b; b = a; a = tampon;
  
  cout<<"Pendant l'échange: a = "<<*a<<" b = "<<*b<<"\n";
}

void main()
{
  int u=5,v=3;

  cout<<"Avant echange: u = "<< u;

  echange(u,v);

  cout<<"Apres echange: u = "<< u;

  getch() ;
}

L'échange n'a pas lieu.

 
#include                                // passage par adresse
#include <conio.h>

void echange(int *a,int *b)
{
  int tampon;
  tampon  = *b; *b = *a; *a = tampon;

  cout<<"Pendant l'échange: a = "<<*a<<" b = "<<*b<<"\n";
}

void main()
{
  int u=5,v=3;

  cout<<"Avant echange: u = "<< u;

  echange(&u,&v);

  cout<<"Apres echange: u = "<< u;

  getch() ;
}

L'échange a lieu.

En C++, on préférera le passage par référence:

Exemple (à tester) et exercice I-12:

#include                         //passage par référence
#include <conio.h>

void echange(int &a,int &b)    //                référence à a et b     
{
  int tampon;
  tampon  = b; b = a; a = tampon;

  cout<<"Pendant l'échange: a = "<<*a<<" b = "<<*b<<"\n";
}

void main()
{
  int u=5,v=3;

  cout<<"Avant echange: u = "<< u;

  echange(u,v);

  cout<<"Apres echange: u = "<< u;

  getch() ;
}

L'échange a lieu. Le compilateur prend en charge le passage par adresse si celui-ci est nécessaire.
Remarquer la simplification de l'écriture de la fonction.

XII- CORRIGE DES EXERCICES

Exercice I-3:

#include 
#include <conio.h>

float puissance(float x,int n)
{                        
  float resultat =1;
  for(int i= 1;i<=n;i++)resultat = resultat * x;
  
  return resultat;
}

void main()
{
  char c=5;int i=10,j=6; float r=2.456,r1,r2,r3,r4,r5;
  r1 = puissance(r,j);
  r2 = puissance(r,c);
  r3 = puissance(j,i);
  r4 = puissance(j,r);
  r5 = puissance(0,4);

  cout << "r1 = " <<r1<<"\n";
  cout << "r2 = " <<r2<<"\n";
  cout << "r3 = " <<r3<<"\n";
  cout << "r4 = " <<r4<<"\n";
  cout << "r5 = " <<r5<<"\n";

  getch() ;
}

Exercice I-4:

#include 
#include <conio.h>

float puissance(float x,int n=4)
{                        
  float resultat=1;
  for(int i=1;i<=n;i++)resultat = resultat * x;

  return resultat;
}

void main()
{
  int j=6; float r=2.456,r1,r2,r3,r4,r5;
  r1 = puissance(r,j);
  r2 = puissance(r);
  r3 = puissance(1.4,j);
  r4 = puissance(1.4);

  cout << "r1 = " <<r1<<"\n";
  cout << "r2 = " <<r2<<"\n";
  cout << "r3 = " <<r3<<"\n";
  cout << "r4 = " <<r4<<"\n";
  
  getch() ;
}

Exercice I-7:

 
#include 
#include <conio.h>

void affiche(float x,int n=0)
{
  int i =1;
  float resultat= 1;

  for(;i<=n;i++)resultat = resultat * x;

  cout << "x = "<<x<< " n = " << n << " resultat = " << resultat <<"\n";
}

void affiche(int n,float x=0)
{
  int i =1;float resultat= 1;

  if (n!=0){for(;i<=n;i++)resultat = resultat * x;}
  else (resultat = 0);

  cout << "n = "<<n<< " x = " << x << " resultat = " << resultat <<"\n";
}

void main()
{
  int u=4,v=0;float y = 2.0,z=0;

  affiche(u);
  affiche(y);
  affiche(y,u);
  affiche(u,y);
  affiche(v,z);
  affiche(z,v);

  getch() ;
}

Exercice I-9:

#include 
#include <conio.h>

void main()
{
  float moyenne =0,*tab = new float[5] ;
  int i=0;

  for(;i<5;i++)
  {
    cout<<"Entrer un nombre: ";
    cin>>tab[i] ;
    moyenne = moyenne + tab[i * ;
  }

  moyenne = moyenne/5;
  cout <<"Moyenne =  "<<moyenne<<"\n";

  delete tab;

  getch() ;
}     

CHAPITRE 2 - PROGRAMMATION ORIENTE OBJET: NOTION DE CLASSE

I- INTRODUCTION
On attend d'un programme informatique :
- l'exactitude (réponse aux spécifications)
- la robustesse (réaction correcte à une utilisation « hors normes »)
- l'extensibilité (aptitude à l'évolution)
- la réutilisabilité (utilisation de modules)
- la portabilité (support d'une autre implémentation)
- l'efficience (performance en termes de vitesse d'exécution et de consommation mémoire)

Les langages évolués de type C ou PASCAL, reposent sur le principe de la programmation structurée (algorithmes + structures de données)

Le C++ et un langage orienté objet. Un langage orienté objet permet la manipulation de classes. Comme on le verra dans ce chapitre, la classe généralise la notion de structure.

Une classe contient des variables (ou « données ») et des fonctions (ou « méthodes ») permettant de manipuler ces variables.

Les langages « orientés objet » ont été développés pour faciliter l'écriture et améliorer la qualité des logiciels en termes de modularité.

Un langage orienté objet sera livré avec une bibliothèque de classes. Le développeur utilise ces classes pour mettre au point ses logiciels.

Rappel sur la notion de prototype de fonction:
En C++, comme en C, on a fréquemment besoin de déclarer des prototypes de fonctions.

Par exemple, dans les fichiers d'en-tête (de type *.h), sont déclarés les prototypes des fonctions appelées par le programme.

Le prototype d'une fonction est constitué du nom de la fonction, du type de la valeur de retour, du type des arguments à passer

Exemples:

void ma_fonction1()
void ma_fonction2(int n, float u)      // prototype «complet»
void ma_fonction2(int, float)            // prototype «réduit»
int ma_fonction3(char *x)                // prototype «complet»
int ma_fonction3(char *)                 // prototype «réduit»
int ma_fonction4(int &u)                 // prototype «complet»
int ma_fonction4(int &)                   // prototype «réduit»

On utilise indifféremment, dans les fichiers d'en-tête, le prototype complet ou le prototype réduit.

II- NOTION DE CLASSE

Exemple (à tester) et exercice II-1 :
(il faut ajuster la temporisation aux performances de la machine utilisée)

#include        // les classes
#include <conio.h>

class point
{
  int x,y;

  public:
    void initialise(int,int);
    void deplace(int,int);

    void affiche();
};

void point::initialise(int abs,int ord)
{
   x = abs; y =ord;
}

void point::deplace(int dx,int dy)
{
  x = x+dx; y = y+dy;
}

void point::affiche()
{
  gotoxy(x,y);
  cout<<"Je suis en "<<x<<"  "<<y<<"\n";
}

void tempo(int duree)
{
  float stop;
  stop  = duree*10000.0;
  for(;stop>0;stop= stop-1.0);
}
  
void main()
{
  point a,b;
  a.initialise(1,4);
  a.affiche();
  tempo(10);
  a.deplace(17,10);
  a.affiche();
  b  =  a;         // affectation autorisee

  tempo(15);
  clrscr();

  b.affiche();

  getch() ;
}

«point» est une classe. Cette classe est constituée des données fonctions membres (ou méthodes) « initialise », « deplace », « affiche ». On déclare la classe en début de programme (données et prototype des fonctions membres), puis on définit le contenu des fonctions membres.

Les données x et y sont dites privées. Ceci signifie que l'on ne peut les manipuler qu'au travers des fonctions membres. On dit que le langage C++ réalise l'encapsulation des données.
a et b sont des objetsde classe «point», c'est-à-dire des variables de type «point».

On a défini ici un nouveau type de variable, propre à cet application, comme on le fait en C avec les structures.

Suivant le principe dit de « l'encapsulation des données », la notation a.x est interdite.

Exercice II-2:
Utiliser la classe « point » précédente. Ecrire une fonction de prototype void test() dans laquelle on déclare un point u, on l'initialise, on l'affiche , on le déplace et on l'affiche à nouveau. Le programme principal main ne contient que l'appel à test.

Exercice II-3:
Ecrire une fonction de prototype void test(point &u) (référence) similaire. Ne pas déclarer de point local dans test. Déclarer un point local a dans le programme principal main et appeler la fonction test en passant le paramètre a.

Exercice II-4:
Ecrire une fonction de prototype point test() qui retourne un point. Ce point sera initialisé et affiché dans test puis déplacé et à nouveau affiché dans main.

III- NOTION DE CONSTRUCTEUR
Un constructeur est une fonction membre systématiquement exécutée lors de la déclaration d'un objet statique, automatique, ou dynamique.

On ne traitera dans ce qui suit que des objets automatiques.

Dans l'exemple de la classe point, le constructeur remplace la fonction membre initialise.

Exemple (à tester) et exercice II-5:

#include        // constructeur
#include <conio.h>

class point
{
  int x,y;
 
  public:
    point(); // noter le type du constructeur (pas de "void")
    void deplace(int,int);
    void affiche();
};

point::point() // initialisation par default
{
  x = 20;
  y = 10;
}

void point::deplace(int dx,int dy)
{
  x = x+dx; y = y+dy;
}

void point::affiche()
{
  gotoxy(x,y);
  cout<<"Je suis en "<<x<<"  "<<y<<"\n";
}

void tempo(int duree)
{
  float stop ;
  stop  = duree*10000.0;

  for(;stop>0;stop= stop-1.0);
}
  
void main()
{
  point a,b;    // les deux points sont initialisés en 20,10
  a.affiche();
  tempo(10);
  a.deplace(17,10);
  a.affiche();
  tempo(15);
  clrscr();

  b.affiche();
  getch() ;
}
<code>

Exemple (à tester) et exercice II-6:
<code cpp>
#include        // constructeur
#include <conio.h>

class point
{
  int x,y;

  public:
    point(int,int); // noter le type du constructeur (pas de "void")
    void deplace(int,int);
    void affiche();
};

point::point(int abs,int ord) // initialisation par default
{x  abs; y  ord;}  // grace au constructeur, ici paramètres à passer

void point::deplace(int dx,int dy)
{
  x = x+dx;
  y = y+dy;
}

void point::affiche()
{
  gotoxy(x,y);
  cout<<"Je suis en "<<x<<"  "<<y<<"\n";
}

void tempo(int duree)
{
  float stop ;
  stop  = duree*10000.0;

  for(;stop>0;stop=  stop-1.0);
}

void main()
{
  point a(20,10),b(30,20);  // les deux points sont initialises:a en 20,10  b en 30,20
  a.affiche();
  tempo(10);
  a.deplace(17,10);
  a.affiche();
  tempo(15);
  clrscr();
  b.affiche();
  getch() ;
}

Exercice II-7:
Reprendre l'exercice II-2, en utilisant la classe de l'exercice II-6

Exercice II-8:
Reprendre l'exercice II-3, en utilisant la classe de l'exercice II-6

Exercice II-9:
Reprendre l'exercice II-4, en utilisant la classe de l'exercice II-6

IV- NOTION DE DESTRUCTEUR
Le destructeur est une fonction membre systématiquement exécutée «à la fin de la vie » d'un objet statique, automatique, ou dynamique.

On ne peut pas passer de paramètres par le destructeur.

On ne traitera dans ce qui suit que des objets automatiques.

Exemple (à tester) et exercice II-10:

#include        // destructeur
#include <conio.h>

class point
{
  int x,y;

  public:
    point(int,int);  
    void deplace(int,int);

    void affiche();

    ~point();        // noter le type du destructeur
};

point::point(int abs,int ord) // initialisation par default
{x = abs; y =  ord;}  // grace au constructeur, ici paramètres à passer
  
void point::deplace(int dx,int dy)
{x =x+dx; y= y+dy;}

void point::affiche()
{
  gotoxy(x,y);
  cout<<"Je suis en "<<x<<"  "<<y<<"\n";
}

point::~point()
{
  cout<<"Frapper une touche...";
  getch();
  cout<<"destruction du point x  ="<<x<<" y= "<<y<<"\n";
}

void tempo(int duree)
{
  float stop ;
  stop  = duree*10000.0;

  for(;stop>0;stop= stop-1.0);
}

void test()
{
  point u(3,7);
  u.affiche();
  tempo(20);
}     

void main()
{
  point a(1,4);
  a.affiche();
  tempo(20);
  test();
  point b(5,10);
  b.affiche();
  getch() ;
}

V- ALLOCATION DYNAMIQUE
Lorsque les membres données d'une classe sont des pointeurs, le constructeur est utilisé pour l'allocation dynamique de mémoire sur ce pointeur.

Le destructeur est utilisé pour libérer la place.

Exemple (à tester) et exercice II-11:

#include     // Allocation dynamique de données membres
#include <stdlib.h>
#include <conio.h>

class calcul
{
  int nbval,*val;
  
  public:
    calcul(int,int);  // constructeur
    ~calcul();    // destructeur

    void affiche();
};

calcul::calcul(int nb,int mul)  //constructeur
{
  int i;
  nbval  = nb;
  val =  new int[nbval] ;  // reserve de la place
  for(i=0;i<nbval;i++)val[i]  = i*mul;
}
 

calcul::~calcul()
{delete val;}  // abandon de la place reservee

void calcul::affiche()
{
  int i;

  for(i =0;i<nbval;i++)cout<<val[i] <<" ";

  cout<<"\n";
}

void main()
{
  clrscr();
  calcul suite1(10,4);
  suite1.affiche();
  calcul suite2(6,8);
  suite2.affiche();

  getch() ;
}

VI- EXERCICES RECAPITULATIFS
Exemple (à tester) et exercice II-12:
Cet exemple ne fonctionne qu'en environnement DOS. Il utilise les fonctions graphiques classiques du TURBO C. On crée une classe « losange », les fonctions membres permettent de manipuler ce losange.

#include <graphics.h>
#include <conio.h>
#include 
#include <dos.h>

class losange
{
  int x,y,dx,dy,couleur;

  public:
    losange();
    void deplace(int,int,int);
    void affiche();
    void efface();
};

losange::losange() // constructeur
{x= 100;y=100;dx=60;dy=100;couleur=BLUE;}

void losange::deplace(int depx,int depy,int coul)
{x =x+depx;y= y+depy;couleur=coul;}

void losange::affiche()
{
  int tab[10] ;
  tab[0] =x;tab[1]= y;tab[2]=x+dx/2;tab[3]=y+dy/2;
  tab[4] =x;tab[5]=y+dy;tab[6]=x-dx/2;tab[7]=y+dy/2;
  tab[8] =x;tab[9]=y;

  setfillstyle(SOLID_FILL,couleur);
  fillpoly(5,tab);
}

void losange::efface()
{
  int tab[10] ;
  tab[0] =x;tab[1]= y;tab[2]=x+dx/2;tab[3]=y+dy/2;
  tab[4] =x;tab[5]=y+dy;tab[6]=x-dx/2;tab[7]=y+dy/2;
  tab[8] =x;tab[9]= y;

  setcolor(getbkcolor());  // pour effacer le contour 
  setfillstyle(SOLID_FILL,getbkcolor());
  fillpoly(5,tab);
}

void init_graph()
{
  int gd,gm;
  detectgraph(&gd,&gm);
  initgraph(&gd,&gm,"c:\\cplus\\bgi");
  setbkcolor(YELLOW);
}

void main()
{
  losange l;
  init_graph();
  l.affiche();
  getch();
  closegraph();
}

Exercice II- 13:
Modifier le programme principal de sorte de faire clignoter le losange tant que l'utilisateur n'a pas appuyé sur une touche.

Exercice II- 14:
Modifier le programme principal de sorte de déplacer le losange d'une position à une autre position, tant que l'utilisateur n'a pas appuyé sur une touche.

VII- CORRIGE DES EXERCICES

Exercice II-2:

#include        // les classes
#include <conio.h>

class point
{
  int x,y;

  public:
    void initialise(int,int);
    void deplace(int,int);
    void affiche();
};

void point::initialise(int abs,int ord)
{x = abs; y = ord;}

void point::deplace(int dx,int dy)
{x = x+dx; y = y+dy;}

void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"  "<<y<<"\n";}

void tempo(int duree)
{float stop ;stop  = duree*10000.0;for(;stop>0;stop= stop-1.0);}

void test()
{
  point u;
  u.initialise(1,4);u.affiche();
  tempo(10);
  u.deplace(17,10);u.affiche();
}

void main()
{test();getch() ;}

Exercice II-3:

#include        // les classes
#include <conio.h>

class point
{
  int x,y;

  public:
    void initialise(int,int);
    void deplace(int,int);
    void affiche();
};

void point::initialise(int abs,int ord)
{x = abs; y = ord;}

void point::deplace(int dx,int dy)
{x = x+dx; y = y+dy;}

void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"  "<<y<<"\n";}

void tempo(int duree)
{float stop ;stop  = duree*10000.0;for(;stop>0;stop= stop-1.0);}

void test(point &u)
{
  u.initialise(1,4);u.affiche();
  tempo(10);
  u.deplace(17,10);u.affiche();
}

void main()
{point a;test(a);getch() ;}

Exercice II-4:
<code cpp>
#include        // les classes
#include <conio.h>

class point
{
  int x,y;
  public:
    void initialise(int,int);
    void deplace(int,int);
    void affiche();
};

void point::initialise(int abs,int ord)
{x = abs; y = ord;}

void point::deplace(int dx,int dy)
{x = x+dx; y = y+dy;}

void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"  "<<y<<"\n";}

void tempo(int duree)
{float stop ;stop  = duree*10000.0;for(;stop>0;stop= stop-1.0);}

point test()
{
  point u;
  u.initialise(1,4);u.affiche();return u;
}

void main()
{
  point a;
  a  = test();
  tempo(10);
  a.deplace(17,10);a.affiche();getch() ;
}

Exercice II-7:

#include        
#include <conio.h>

class point
{
  int x,y;

  public:
    point(int,int); // noter le type du constructeur (pas de "void")
    void deplace(int,int);
    void affiche();
};

point::point(int abs,int ord) // initialisation par default
{x = abs; y = ord;}  // grace au constructeur, ici paramètres à passer

void point::deplace(int dx,int dy)
{x  = x+dx; y = y+dy;}

void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"  "<<y<<"\n";}

void tempo(int duree)
{float stop ;stop  = duree*10000.0;for(;stop>0;stop= stop-1.0);}

void test()
{
  point u(1,4);
  u.affiche();
  tempo(10);
  u.deplace(17,10);
  u.affiche();
}

void main()
{test();getch() ;}

Exercice II-8:

#include        // les classes
#include <conio.h>

class point
{
  int x,y;

  public:
    point(int,int); // noter le type du constructeur (pas de "void")
    void deplace(int,int);
    void affiche();
};

point::point(int abs,int ord) // initialisation par default
{x = abs; y = ord;}  // grace au constructeur, ici paramètres à passer

void point::deplace(int dx,int dy)
{x = x+dx; y =  y+dy;}
 
void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"  "<<y<<"\n";}

void tempo(int duree)
{float stop ;stop  = duree*10000.0;for(;stop>0;stop= stop-1.0);}

void test(point &u)
{
  u.affiche();
  tempo(10);
  u.deplace(17,10);u.affiche();
}

void main()
{point a(1,4);test(a);getch() ;}

Exercice II-9:

#include        // les classes
#include <conio.h>

class point
{
  int x,y;

  public:
    point(int,int); // noter le type du constructeur (pas de "void")
    void deplace(int,int);
    void affiche();
};

point::point(int abs,int ord) // initialisation par default
{x = abs; y = ord;}  // grace au constructeur, ici paramètres à passer

void point::deplace(int dx,int dy)
{x = x+dx; y = y+dy;}

void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"  "<<y<<"\n";}

void tempo(int duree)
{float stop ;stop  = duree*10000.0;for(;stop>0;stop= stop-1.0);}

point test()
{
  point u(5,6);
  u.affiche();return u;
}

void main()
{
  point a(1,4);
  a.affiche();
  tempo(15);
  a  =  test();
  tempo(10);
  a.deplace(17,10);a.affiche();
}

Exercice II-13:

void main()
{
  losange l;
  init_graph();
  while(!kbhit())
  {
    l.affiche(); delay(500);
    l.efface(); delay(500);
  }

  getch();closegraph();
}

Exercice II-14:

void main()
{
  losange l;
  init_graph();
  while(!kbhit())
  {
    l.affiche(); delay(500);l.efface();
    l.deplace(150,150,RED);
    l.affiche();delay(500);l.efface();
    l.deplace(-150,-150,BLUE);
  }

  getch();closegraph();
}

CHAPITRE 3 - PROPRIETES DES FONCTIONS MEMBRES

I- SURDEFINITION DES FONCTIONS MEMBRES
En utilisant la propriété de surdéfinition des fonctions du C++, on peut définir plusieurs constructeurs, ou bien plusieurs fonctions membres, différentes, mais portant le même nom.

Exemple (à tester) et exercice III-1:
Définition de plusieurs constructeurs:

#include        // Surdefinition de fonctions
#include <conio.h>

class point
{
  int x,y;

  public:
    point();   // constructeur 1
    point(int);// constructeur 2
    point(int,int);// constructeur 3
    void affiche();
};

point::point()  // constructeur 1
{x = 0;y=0;}

point::point(int abs)   // constructeur 2
{x = abs; y = abs;}

point::point(int abs,int ord)    // constructeur 3
{x = abs; y =  ord;}

void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<" "<<y<<"\n";}

void main()
{
  clrscr();
  point a,b(5);
  a.affiche();
  b.affiche();
  point c(3,12);
  c.affiche();
  getch() ;
}

Exercice III-2: Surdéfinition d'une fonction membre
Ecrire une deuxième fonction affiche de prototype void point::affiche(char *message)
Cette fonction donne la possibilité à l'utilisateur d'ajouter, à la position du point, un message sur l'écran.

II- FONCTIONS MEMBRES « EN LIGNE »
Le langage C++ autorise la description des fonctions membres dès leur déclaration dans la classe. On dit que l'on écrit une fonction « inline ».

Il s'agit alors d'une « macrofonction »: A chaque appel, il y a génération du code de la fonction et non appel à un sous-programme.

Les appels sont donc plus rapides mais cette méthode génère davantage de code.

Exemple (à tester) et exercice III-3:
Comparer la taille des fichiers exIII_1.obj et exIII_3.obj

#include        // Surdefinition de fonctions
#include <conio.h>

class point
{
  int x,y;

  public:
    point(){x  =0;y= 0;}  // constructeur 1
    point(int abs){x=abs;y=abs;}// constructeur 2
    point(int abs,int ord){x=abs;y=ord;}// constructeur 3
    void affiche();
};

void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<" "<<y<<"\n";}

void main()
{
  point a,b(5);
  a.affiche();
  b.affiche();
  point c(3,12);
  c.affiche();
  getch() ;
}

III- INITIALISATION DES PARAMETRES PAR DEFAUT

Exemple (à tester) et exercice III-4:

#include        // Fonctions membres « en ligne »
#include <conio.h>

class point
{
  int x,y;
  
  public:
    point(int abs=0,int ord=2)
    {x=abs;y=ord;}// constructeur
     
    void affiche(char* = "Position du point"); // argument par defaut
};

void point::affiche(char *message)
{
  gotoxy(x,y-1);cout<<message;
  gotoxy(x,y);cout<<"Je suis en "<<x<<" "<<y<<"\n";
}

void main()
{
  point a,b(40);
  a.affiche();
  b.affiche("Point b");
  char texte[10] ="Bonjour";
  point c(3,12);
  c.affiche(texte);
  getch() ;
}

IV- OBJETS TRANSMIS EN ARGUMENT D'UNE FONCTION MEMBRE
Quand on passe comme paramètre à une fonction membre ... un objet de la classe à laquelle appartient cette fonction:

1- Passage par valeur

Exemple (à tester) et exercice III-5:

#include 
#include <conio.h>                // objets transmis en argument d'une fonction membre

class point
{
  int x,y;
  public:
    point(int abs 0,int ord 2){x=abs;y=ord;}// constructeur
    int coincide(point);
};

int point::coincide(point pt)
{if ((pt.x =x) && (pt.y= y)) return(1);else return(0);}
// noter la dissymetrie des notations pt.x et x

void main()
{
  int test1,test2;
  point a,b(1),c(0,2);
  test1 = a.coincide(b);
  test2 = b.coincide(a);

  cout<<"a et b:"<<test1<<" ou "<<test2<<"\n";
  test1 = a.coincide(c);
  test2 =  c.coincide(a);

  cout<<"a et c:"<<test1<<" ou "<<test2<<"\n";
  getch() ;
}

Noter que l'on rencontre la notation « pt.x » ou « pt.y » pour la première fois. Elle n'est autorisée qu'à l'intérieur d'une fonction membre (x et y membres privés de la classe).

On verra plus tard que le passage d'un objet par valeur pose problème si certains membres de la classe sont des pointeurs. Il faudra alors prévoir une allocation dynamique de mémoire via un constructeur.

2- Passage par adresse

Exercice III-6:
Modifier la fonction membre coincide de l'exercice prcédent de sorte que son prototype devienne int point::coincide(point *adpt). Ré-écrire le programme principal en conséquence.

3- Passage par référence

Exercice III-7:
Modifier à nouveau la fonction membre coincide de sorte que son prototype devienne int point::coincide(point &pt). Ré-écrire le programme principal en conséquence.

V- EXERCICES RECAPITULATIFS
On définit la classe vecteur comme ci-dessous:

class vecteur
{
  float x,y;

  public:
    vecteur(float,float);
    void homotethie(float);
    void affiche();
};

vecteur::vecteur(float abs   =0.,float ord =  0.)
{x=abs;y=ord;}

void vecteur::homotethie(float val)
{x = x*val;  y= y*val;}

void vecteur::affiche()
{cout<<"x = "<<x<<"  y =  "<<y<<"\n";}       

Exercice III-8:
La mettre en oeuvre dans void main(), en ajoutant une fonction membre float det(vecteur) qui retourne le déterminant des deux vecteurs (celui passé en paramètre et celui de l'objet).

Exercice III-9:
Modifier la fonction déterminant de sorte de passer le paramètre par adresse.

Exercice III-10:
Modifier la fonction déterminant de sorte de passer le paramètre par référence.

VI- OBJET RETOURNE PAR UNE FONCTION MEMBRE
Que se passe-t-il lorsqu'une fonction membre retourne elle-même un objet ?

1- Retour par valeur
Exemple (à tester) et exercice III-11:
(la fonction concernée est la fonction symetrique)
<code cpp>
#include <iostream.h>
#include <conio.h>

// La valeur de retour d'une fonction est un objet
// Transmission par valeur

class point
{
  int x,y;

  public:
    point(int abs = 0,int ord = 0){x=abs;y=ord;}// constructeur
    point symetrique();
    void affiche();
};

point point::symetrique()
{
  point res;
  res.x = -x;  res.y = -y;
  return res;
}

void point::affiche()
{
  cout<<"Je suis en "<<x<<" "<<" "<<y<<"\n";
}

void main()
{
  point a,b(1,6);
  a=b.symetrique();a.affiche();b.affiche();
  getch() ;
}

2- Retour par adresse (***)
Exemple (à tester) et exercice III-12:

#include <iostream.h>
#include <conio.h>

// La valeur de retour d'une fonction est un objet
// Transmission par adresse

class point
{
  int x,y;

  public:
    point(int abs = 0,int ord = 0){x=abs;y=ord;}// constructeur
    point *symetrique();
    void affiche();
};

point *point::symetrique()
{
  point *res;
  res = new point;
  res->x = -x;  res->y = -y;
  return res;
}

void point::affiche()
{cout<<"Je suis en "<<x<<" "<<y<<"\n";}

void main()
{
  point a,b(1,6);
  a = *b.symetrique();a.affiche();b.affiche();
  getch() ;
}

3- Retour par référence (***)
La valeur retournée l'est par référence. On en verra l'usage dans un prochain chapitre.

Exemple (à tester) et exercice III-13:

#include <iostream.h>
#include <conio.h>
// La valeur de retour d'une fonction est un objet
// Transmission par reference

class point
{
  int x,y;
  public:
    point(int abs = 0,int ord = 0){x=abs;y=ord;}// constructeur
    point &symetrique();
    void affiche();
};

point &point::symetrique()  // La variable res est obligatoirement static
{
  static point res;          // Pour passer par reference
  res.x = -x;  res.y = -y;
  return res;
}

void point::affiche()
{cout<<"Je suis en "<<x<<" "<<y<<"\n";}

void main()
{
  point a,b(1,6);
  a=b.symetrique();a.affiche();b.affiche();
  getch() ;
}

Remarque: « res » et « b.symetrique »occupent le même emplacement mémoire (car « res » est une référence à « b.symetrique ». On déclare donc « res » comme variable static, sinon, cet objet n'existerait plus après être sorti de la fonction.

VII- EXERCICES RECAPITULATIFS

Exercice III-14:
Reprendre la classe vecteur. Modifier la fonction homotéthie, qui retourne le vecteur modifié. (prototype: vecteur vecteur::homotethie(float val)).

Exercice III-15 (***):
Même exercice, le retour se fait par adresse.

Exercice III-16 (***):
Même exercice, le retour se fait par référence.

VIII- LE MOT CLE « THIS »
Ce mot désigne l'adresse de l'objet invoqué. Il est utilisable uniquement au sein d'une fonction membre.

Exemple (à tester) et exercice III-17:

#include <conio.h>                // le mot cle THIS: pointeur sur l'objet l'ayant appel
#include <iostream.h>          // utilisable uniquement dans une fonction membre

class point
{
  int x,y;

  public:
    point(int abs=0,int ord=0) // constructeur en ligne
    {x=abs;y=ord;}

  void affiche();
};

void point::affiche()
{cout<<"Adresse: "<<this<<" - Coordonnees: "<<x<<" "<<y<<"\n";}

void main()
{
  point a(5),b(3,15);
  a.affiche();b.affiche();
  getch() ;
}

Exercice III-18:
Remplacer, dans l'exercice III-6, la fonction coincide par la fonction suivante:

int point::coincide(point *adpt)
{
  if ((this->x == adpt->x) && (this->y == adpt->y))
   return(1);
  else
  return(0);
}

IX- EXERCICE RECAPITULATIF

Exercice III-19:
Reprendre la classe vecteur, munie du constructeur et de la fonction d'affichage. Ajouter:
- Une fonction membre float vecteur::prod_scal(vecteur) qui retourne le produit scalaire des 2 vecteurs.
- Une fonction membre vecteur vecteur::somme(vecteur) qui retourne la somme des 2 vecteurs.

XI- CORRIGE DES EXERCICES

Exercice III-2:

 
#include <iostream.h>       // Surdefinition de fonctions
#include <conio.h>

class point
{
  int x,y;
  
  public:
    point();   // constructeur 1
    point(int);// constructeur 2
    point(int,int);// constructeur 3
    void affiche();
    void affiche(char *); // argument de type chaine
};

point::point()  // constructeur 1
{x=0;y=0;}

point::point(int abs)   // constructeur 2
{x=y=abs;}

point::point(int abs,int ord)    // constructeur 3
{x = abs; y = ord;}

void point::affiche()               // affiche 1
{gotoxy(x,y);cout<<"Je suis en "<<x<<" "<<y<<"\n";}

void point::affiche(char *message)               // affiche 2
{
  gotoxy(x,y-1);cout<<message;
  gotoxy(x,y);cout<<"Je suis en "<<x<<" "<<y<<"\n";
}

void main()
{
  point a,b(5);
  a.affiche();
  b.affiche("Point b:");
  point c(3,12);
  char texte[10] = "Bonjour";
  c.affiche(texte);
  getch() ;
}

Exercice III-6:

#include <iostream.h>
#include <conio.h>

// objets transmis en argument d'une fonction membre - transmission de l'adresse

class point
{
  int x,y;

  public:
    point(int abs = 0,int ord = 2){x=abs;y=ord;}// constructeur
    int coincide(point *);
};

int point::coincide(point *adpt)
{if ((adpt->x == x) && (adpt->y == y)) return(1);else return(0);}
// noter la dissymetrie des notations pt->x et x

void main()
{
  point a,b(1),c(0,2);
  int test1,test2;
  test1 = a.coincide(&b);
  test2 = b.coincide(&a);
  cout<<"a et b:"<<test1<<" ou "<<test2<<"\n";
  test1 = a.coincide(&c);
  test2 = c.coincide(&a);
  cout<<"a et c:"<<test1<<" ou "<<test2<<"\n";
  getch() ;
}

Exercice III-7:

#include <iostream.h>
#include <conio.h>

// objets transmis en argument d'une fonction membre - transmission par reference

class point
{
  int x,y;

  public:
    point(int abs = 0,int ord = 2){x=abs;y=ord;}// constructeur
    int coincide(point &);
};

int point::coincide(point &pt)
{if ((pt.x == x) && (pt.y == y)) return(1);else return(0);}
// noter la dissymetrie des notations pt.x et x

void main()
{
  point a,b(1),c(0,2);
  int test1,test2;
  test1 = a.coincide(b);
  test2 = b.coincide(a);
  cout<<"a et b:"<<test1<<" ou "<<test2<<"\n";
  test1 = a.coincide(c);
  test2 = c.coincide(a);
  cout<<"a et c:"<<test1<<" ou "<<test2<<"\n";
  getch() ;
}

Exercice III-8:

#include <iostream.h>
#include <conio.h>

// Classe vecteur - Fonction membre determinant - Passage par valeur
class vecteur
{
  float x,y;

  public:
    vecteur(float,float);
    void homotethie(float);
    void affiche();
    float det(vecteur);
};

vecteur::vecteur(float abs =0.,float ord = 0.)
{x=abs;y=ord;}

void vecteur::homotethie(float val)
{x = x*val;  y = y*val;}

void vecteur::affiche()
{cout<<"x = "<<x<<"  y = "<<y<<"\n";}

float vecteur::det(vecteur w)
{
  float res;
  res = x * w.y - y * w.x;
  return res;
}

void main()
{
  vecteur v(2,6),u(4,8);
  v.affiche();v.homotethie(2);v.affiche();
  cout <<"Determinant de (u,v) = "<<v.det(u)<<"\n";
  cout <<"Determinant de (v,u) = "<<u.det(v)<<"\n";getch() ;
}

Exercice III-9:

#include <iostream.h>
#include <conio.h>

// Classe vecteur - Fonction membre determinant - Passage par adresse
class vecteur
{
  float x,y;

  public:
    vecteur(float,float);
    void homotethie(float);
    void affiche();
    float det(vecteur *);
};

vecteur::vecteur(float abs =0.,float ord = 0.)
{x=abs;y=ord;}

void vecteur::homotethie(float val)
{x = x*val;  y = y*val;}

void vecteur::affiche()
{cout<<"x = "<<x<<"  y = "<<y<<"\n";}

float vecteur::det(vecteur *w)
{
  float res;
  res = x * w->y - y * w->x;
  return res;
}

void main()
{
  vecteur v(2,6),u(4,8);
  v.affiche();v.homotethie(2);v.affiche();
  cout <<"Determinant de (u,v) = "<<v.det(&u)<<"\n";
  cout <<"Determinant de (v,u) = "<<u.det(&v)<<"\n";getch() ;
}

Exercice III-10:

#include <iostream.h>
#include <conio.h>

// Classe vecteur - Fonction membre determinant - Passage par reference
class vecteur
{
  float x,y;

  public:
    vecteur(float,float);
    void homotethie(float);
    void affiche();
    float det(vecteur &);
};

vecteur::vecteur(float abs =0,float ord = 0)
{x=abs;y=ord;}

void vecteur::homotethie(float val)
{x = x*val;  y = y*val;}

void vecteur::affiche()
{cout<<"x = "<<x<<"  y = "<<y<<"\n";}

float vecteur::det(vecteur &w)
{
  float res;
  res = x * w.y - y * w.x;
  return res;
}

void main()
{
  vecteur v(2,6),u(4,8);
  v.affiche();v.homotethie(2);v.affiche();
  cout <<"Determinant de (u,v) = "<<v.det(u)<<"\n";
  cout <<"Determinant de (v,u) = "<<u.det(v)<<"\n";getch() ;
}

Exercice III-14:

#include <iostream.h>
#include <conio.h>

// Classe vecteur - Fonction homotethie - Retour par valeur
class vecteur
{
  float x,y;

  public:
    vecteur(float,float); // Constructeur
    vecteur homotethie(float);
    void affiche();
};

vecteur::vecteur(float abs =0,float ord = 0)
{x=abs;y=ord;}

vecteur vecteur::homotethie(float val)
{
  vecteur res;
  res.x = x*val;  res.y = y*val;
  return res;
}

void vecteur::affiche()
{cout<<"x = "<<x<<"  y = "<<y<<"\n";}

void main()
{
  vecteur v(2,6),u;
  v.affiche();u.affiche();
  u = v.homotethie(4);
  u.affiche();getch() ;
}

Exercice III-15:

#include <iostream.h>
#include <conio.h>

// Classe vecteur - Fonction homotethie - Retour par adresse
class vecteur
{
  float x,y;

  public:
     vecteur(float,float); // Constructeur
     vecteur  *homotethie(float);
     void affiche();
};

vecteur::vecteur(float abs =0.,float ord = 0.)    // Constructeur
{x=abs;y=ord;}

vecteur *vecteur::homotethie(float val)
{
  vecteur *res;
  res = new vecteur;
  res->x = x*val;  res->y = y*val;
  return res;
}

void vecteur::affiche()
{cout<<"x = "<<x<<"  y = "<<y<<"\n";}

void main()
{
  vecteur v(2,6),u;
  v.affiche();u.affiche();
  u = *v.homotethie(4);
  u.affiche();getch() ;
}
Ce document intitulé « Cours c++ » issu de CodeS SourceS (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.