Les constructeurs de promotion ou de conversion

Un constructeur de promotion ou de conversion d'une classe MyClass est :

1)
MyClass(const MyClass&) est appelé constructeur de recopie.
class Complex
{
private:
    double re;
    double im;
 
public:
    Complex(): re(0.0), im(0.0)         // Constructeur par défaut.
    {}
    Complex(const Complex& theSource):  // Constructeur de recopie
        re(theSource.re), im(theSource.im)
    {}
    Complex(double aFloat):             // Conversion
        re(aFloat), im(0.0)
    {}
    Complex(double theReal, double theImaginary)
        re(theReal), im(theImaginary)   // Constructeur spécialisé
    {}
};
Dans la classe Complex, le constructeur Complex(double aFloat) définit un constructeur de conversion qui prend une valeur ayant pour type double comme argument. Ce constructeur permet de convertir une valeur flottante en un nombre complexe réel. Il s'agit a priori d'une fonction de conversion, c'est pour cela que ce type d'opérateur porte comme constructeur de contruction ou de promotion. Cette conversion s'effectue de manière automatique. Ainsi, vous pouvez écrire le code suivant :
#include<cmath>
 
double Norm(Complex aComplex)
{
    return std::sqrt(std::pow(aComplex.getRe(), 2), std::pow(aComplex.getIm(), 2);    
}
 
int main()
{
    Norm(1.0);
}
La fonction Norm prend un nombre complexe. Cependant, l'argument fourni est une valeur 1.0 de type double. Puisqu'il est possible de convertir une valeur de type double en un objet de type Complex en appelant le constructeur Complex(double), la valeur 1.0 est converti en un objet Complex ayant comme parte réelle 1.0 et partie imaginaire 0.0.. Aucun message d'avertisssement n'est généré au moment de cette conversion. Cependant, parfois, nous ne souhaitons pas que la conversion puisse se faire de manière implicite. Nous souhaitons controler cette opération. Dans ce cas, nous devons ajouter le mot clé explicit devant la déclaration du constructeur de conversion.
    explicit Complex(double aFloat):             // Conversion
        re(aFloat), im(0.0)
    {}
Dans ce cas, l'appel à la fonction Norm:
int main()
{
    Norm(1.0);
}
échoue au moment de la compilation, Norm n'étant pas définie pour les valeurs de type double. Par contre, si nous forçons la conversion, alors l'appel pourra être effectué :
int main()
{
    Norm(Complex(1.0));
}