Vous êtes sur la page 1sur 5

Mohammed AIRAJ

GSEII-1
ENSAF 2023/2024

TD/TP 2 : Les classes : Avancée

Exercice 1 :

Soit la classe vecteur3d définie par :


class vecteur3d
{
float x, y, z ;
public :
vecteur3d (float c1=0.0, float c2=0.0, float c3=0.0)
{
x = c1 ; y = c2 ; z = c3 ;
}
};

Écrire une fonction indépendante coincide, amie de la classe vecteur3d, permettant de


savoir si deux vecteurs ont les mêmes composantes ; elle retourne les valeurs entières
1 ou 0.

Exercice 2 :

Créer deux classes (dont les membres données sont privés) :

• l’une, nommée vect, permettant de représenter des vecteurs à 3 composantes de


type double ; elle comportera un constructeur et une fonction membre d’affichage
;

• l’autre, nommée matrice, permettant de représenter des matrices carrées de


dimension 3 x 3 ; elle comportera un constructeur avec un argument (adresse d’un
tableau de 3 x 3 valeurs) qui initialisera la matrice avec les valeurs
correspondantes.

Réaliser une fonction amie indépendante prod permettant de fournir le vecteur


correspondant au produit d’une matrice par un vecteur.

Écrire un petit programme de test.


Exercice 3 :

1) Définir la classe Point qui possède les variables x et y de type float et les méthodes
suivantes :
Un constructeur qui initialise x et y et qui possède les valeurs 0.f,0.f, par défaut.
Une méthode affiche() qui imprime les valeurs x et y.
Les accesseurs de x et de y, getX, setX, getY, setY.
2) Ecrire un programme Test qui instancie un point P1 avec les valeurs définies par
défaut, un point P2 (1.f,2.f) et qui affiche ces points.
Modifier les valeurs de P1 et de P2 par (3.f,4.f) et (5.f,6.f) et afficher de nouveau les
deux points.
3) Définir une variable PP1 de type Point * et l’initialiser avec l’opérateur new qui
prend comme argument le Point(10.f,20.f) , afficher ce point défini dynamiquement.
4) Se définir un tableau Ptab de points de dimension 5. Dans une boucle où x varie de
0.f à 1. et y de 1.f à 0.f , par pas de 0.25, initialiser les variables x et y des points du
tableau PTab.
5) Libérer la mémoire occupée par PP1 et par Ptab.
6) Créer un tableau de Point * dynamiquement, de dimension 2 et initialiser ce tableau
et chaque sous-tableau (selon votre imagination) de dimension 3.

Compléments de cours :
Le qualificatif const associé à une méthode.
Une méthode ne s’applique pas par défaut à un objet déclaré const.
Par exemple :
const Point P(1.f,2.f) ; // P déclaré constant.
L’appel P.affiche() implique une erreur de compilation.
Pour autoriser une méthode à s’appliquer à un objet constant, il faut dans son prototype et sa
définition utiliser le qualificatif const :
void affiche () const ; // Prototype défini dans Point.hxx
void Point ::affiche() const
{
….
}
Cette double déclaration peut sembler redondante mais elle est indispensable.

Exercice 4 :
Problématique des objets dynamiques, attributs d’une classe.
Définir la classe Vecteur qui possède les attributs suivants :
⚫ int N ( Dimension du vecteur)
⚫ float * Coor ( Composantes du vecteur )
Ecrire le constructeur usuel qui admet un entier (valeur par défaut 0) et un tableau de
float (float *, valeur par défaut NULL) comme arguments et le destructeur
correspondant.
Surdéfinir le constructeur par recopie.
Tester la classe Vecteur dans un programme Test qui instancie un vecteur V1 avec
toutes les valeurs par défauts, un vecteur V2 dont la dimension vaut 5 et les
composantes sont égales à zéro.
Vérifier que l’instruction Vecteur V3 = V2 implique l’appel au constructeur par
recopie.

Surdéfinition des opérateurs.


Surdéfinir l’opérateur[] et l’opérateur d’affectation. Définir dans le programme Test un
nouveau vecteur V4 de dimension 5 et de valeurs (0,1,2,3,4)
Vérifier que l’instruction V2=V4 implique l’appel de l’opérateur d’affectation.

Exercice 5 :

La classe Matrice.
Définir la classe Matrice qui possède les attributs suivants :
⚫ int N // Rang de la matrice carrée NxN
⚫ double * Coef // Tableau unidimensionnel de dimension NxN
⚫ double ** M // Tableau de pointeurs, double , tel que: M[i] = &Coef[i*N]
pour i = 0, N-1
Ecrire comme précédemment, le contructeur usuel, le destructeur, le constructeur par
recopie et surdéfinr l'opérateur d'affectation et l'opérateur [].

Ecrire la méthode Gauss qui décomposera la matrice en LU


(décomposition de Gauss)
void Gauss ( )
Ecrire la méthode Resoudre qui effectue la descente et la remontée du système :
Vecteur Resoudre(const Vecteur &) ;

Compléments de cours : Surdéfinition des opérateurs << et >>.

La classe prédéfinie en C++ qui gère les flots de sortie est la classe ostream.
De façon à pouvoir écrire cout << V1, on va surdéfinir l’opérateur << de la manière
suivante :
en-tête:
#include <iostream>
using namespace std;

ostream & operator << (ostream & sortie , const Vecteur & V)
{
for ( int i= 0 ; i < V.N ; i++)
sortie << V[I] ;
sortie << endl;
}
La classe prédéfinie en C++ qui gère les flots d’entrée est la classe istream.
De façon à pouvoir écrire le vecteur V1 à partir du terminal, on va surdéfinir l’opérateur
>> de la manière suivante :
istream & operator >> ( istream & entree , const Vecteur & V)
{
for ( int i= 0 ; i < V.N ; i++)
entree >> V[I];
}
Les opérateurs << et >> sont des fonctions indépendantes, déclarées amies de la classe
Vecteur.
Enfin écrire l’opérateur +, addition de 2 vecteurs.

Variables et fonctions statiques.

Chaque attribut d’une classe est propre à un objet de cette classe. Cependant il est possible
de définir des variables communes à tous les objets de la classe avec le qualificatif static.
static int Count ;
Cette variable particulière sera initialisée dans le fichier .cpp, de la manière suivante :
int Vecteur::Count = 0 ;
A chaque construction d’objet de la classe Vecteur, cette variable sera incrémentée de 1, à
chaque destruction décrémentée de 1. Ainsi on peut compter le nombre d’instances d’une
classe.
De même, des fonctions membres de la classe peuvent être déclarées statiques et donc être
indépendantes d’un quelconque objet de la classe. Ces fonctions ne concerneront que des
données déclarées statiques.
Exemple la fonction qui retourne le nombre d’instances au moment de son appel.
static int NombreObjets() ;
int Vecteur::NombreObjets()
{
return Count ;
}
Cette fonction peut être appelée de la manière suivante :
cout << “nombre d’objets de la classe Vecteur : “ << Vecteur::NombreObjets() << endl ;
Donc peut être appeler indépendamment de l’existence d’un quelconque objet de la classe.

Douloureux et épineux problème de la conversion

Deux règles fondamentales :

Par passage en argument, le compilateur décide automatiquement d’une conversion si


cela est possible.
Le compilateur ne prend pas l’initiative de choisir une option plutôt qu’une autre,
quand les deux sont possibles. Attention donc de ne pas lui proposer plusieurs solutions
sinon erreur de compilation.
Complément de cours

Fonctions d'opérateur Cast surchargées


Des fonctions d'opérateur de conversion surchargées peuvent être définies pour convertir des
objets de types définis par l'utilisateur en types fondamentaux ou en objets d'autres types
définis par l'utilisateur.

Les prototypes

MyClass::operator int() const; //(i)

MyClass::operator OtherClass() const; //(ii)

déclarent des fonctions d'opérateur de cast surchargées qui peuvent convertir un objet de type
défini par l'utilisateur, ici MyClass, en un entier (i) ou en un objet de type défini par
l'utilisateur, ici OtherClass (ii), respectivement.

Exercice 6 :

Ecrire une classe Complex. La tester.

Se définir l’opérateur de conversion de la classe Complex → classe Point et


réciproquement de la classe Point → classe Complex et vérifier les deux conversions dans
un programme principal Test.cpp.
Surdéfinir la méthode operator + dans la classe Complex et vérifier que les deux cas
suivants marchent :
Complex z3 =z1+z2 ;
Complex z4 = z1+1.f ;
Pourquoi le dernier cas fonctionne ?
Peut-on écrire Complex z5 = 1.f+z1 ?
Quelle solution peut-on proposer ?
Allons plus loin, écrire un point comme la somme d’un complexe et d’un point et
réciproquement un complex comme la somme d’un complexe et d’un point.
Ecrire maintenant un point comme somme de deux points.
Proposer une solution raisonnable pour les deux composants Point et Complex.

Vous aimerez peut-être aussi