This is an old revision of the document!
Partie I – Surcharge d’opérateurs
Question n°1
Créer un projet dans lequel vous définissez une classe de nombre complexe qui aura typiquement la structure suivante :
#ifndef complexHPP
#define complexHPP
class Complex
{
private:
double mRealPart;
double mImaginaryPart;
public:
Complex();
~Complex();
...
};
#endif
Question n°1.1
Ajouter à cette classe un ou plusieurs opérateurs de conversion convertissant un nombre flottant en un nombre complexe.
Pour convertir un nombre en virgule flottante en un nombre complexe, il faut définir de nouveaux constructeurs qui vont prendre un seul argument qui aura pour type le type d'un nombre à virgule flottante.
Sachant que dans le cas présent, nous souhaitons pouvoir transformer automatiquement un nombre à virgule flottante x
en un nombre complexe si un nombre complexe est attendu, le constructeur ne doit pas être déclarée comme explicit
.
De fait, il est nécessaire d'ajouter les constructeurs suivant pour les types float
et double
.
class Complex
{
private:
...
public:
Complex(double aReal) : mRealPart(aReal), mImaginaryPart(0.0) {}
Complex(float aReal) : mRealPart(aReal), mImaginaryPart(0.0) {}
...
};
Il n'est nullement souhaitable de se limiter aux nombres à virgule flottante, nous pouvons ajouter des opérations de conversions identiques pour les nombres entiers :
class Complex
{
private:
...
public:
Complex(double aReal) : mRealPart(aReal), mImaginaryPart(0.0) {}
Complex(float aReal) : mRealPart(aReal), mImaginaryPart(0.0) {}
Complex(int aReal) : mRealPart((double)aReal), mImaginaryPart(0.0) {}
Complex(unsigned in aReal) : mRealPart((double)aReal), mImaginaryPart(0.0) {}
...
};
Question n°1.2
Ajouter à cette classe une fonction qui affiche le nombre complexe sur la console.
Nous pouvons ajouter une fonction simple qui affiche le résultat sur la console. Cette fonction affiche la représentation minimale du nombre complexe.
class Complex
{
private:
...
public:
void print() const
{
if(mRealPart != 0.0)
{
std:cout << mRealPart;
if(mImaginaryPart != 0.0)
std::cout << " + " << mImaginaryPart << " I";
}
else if(mImaginaryPart != 0.0)
std::cout << " + " << mImaginaryPart << " I";
else
std::cout << "0.0";
}
...
};
Question n°1.3
Créer deux fonctions statiques créant des nombre complexes, l’une créant un nombre complexe à partir d’une paire correspondant à la partie réelle et imaginaire, l’autre créant un nombre complexe à partir de la paire (ρ,θ) correspondant à la notation polaire de ce nombre.
La difficulté, c'est qu'un nombre complexe admet deux représentations canoniques, une représentation sous la forme d'une partie réelle et une partie imaginaire ou au contraire une représentation sous la forme de coordonnées polaire.
Si nous souhaitons définir un constructeur pour construire un nombre complexe à partir de ses parties réelles et imaginaires, nous allons nous retrouver avec un constructeur ayant comme signature, la signature suivante :
Complex(double theRealPart, double theImaginaryPart);
Le constructeur qui construit un nombre complex à partie des coordonnées polaires aura la signature suivante :
Complex(double rho, double theta);
c'est à dire que les deux constructeurs auront la même signature Complex(double, double)
et le compilateur se retrouvera avec deux définitions différentes du même constructeur, d'où une erreur au moment de la compilation.
Alors il existe plusieurs
Question n°1.4
Créer une variable globale ayant comme type la classe complexe et ayant pour valeur la valeur imaginaire 1.
Question n°1.5
Tester le bon comportement de votre classe sur des exemples simples. Notamment, est-il possible d’écrire désormais :
Complex complexValue = 3.3 + 5 * I;
Question n°2
Nous considérons les opérations de base simple que sont l’addition et la soustraction.
Question n°2.1
Proposer une surcharge des opérations + et –. Implanter ces dernières et tester.
Complex operator + (const Complex& aRightValue) const;
Complex operator - (const Complex& aRightValue) const;
Question n°2.2
Proposer une surcharge des opérations + et –. Implanter ces dernières et tester.
Complex operator + (double aLeftValue, const Complex& aRightValue);
Complex operator – (double a aLeftValue, const Complex& aRightValue);
Expliquer la différence avec les opérations précédentes ?
Question n°2.3
Tester le bon comportement de votre classe sur des exemples simples. Notamment, est-il possible d’écrire désormais :
Complex complexValue = 3.3 + 5 * I;
Question n°2.4
Proposer une surcharge des opérations += et –=. Implanter ces dernières et tester.
Complex& operator += (const Complex& aRightValue);
Complex& operator -= (const Complex& aRightValue);
Expliquer pourquoi les signatures des operations += et -= sont différentes de celles des operations + et - ?
Question n°3
Nous considérons les opérations de base que sont la multiplication et la division.
Question n°3.1
Proposer deux fonctions de conversion entre la représentation polaire et la représentation canonique des nombres complexes et implanter les.
Question n°3.2
Proposer une surcharge des opérations + et –. Implanter ces dernières et tester.
Complex operator * (const Complex& aRightValue) const;
Complex operator / (const Complex& aRightValue) const;
Question n°3.3 (optionnel)
Proposer une surcharge des opérations + et –. Implanter ces dernières et tester.
Complex& operator *= (const Complex& aRightValue);
Complex& operator /= (const Complex& aRightValue);