2010-02-20 6 views
7

Je pensais que les constructeurs contrôlaient l'initialisation et l'assignation des fonctions opérateur = C++. Alors pourquoi ce code fonctionne-t-il?Affectation et initialisation en C++

#include <iostream> 
#include <cmath> 
using namespace std; 

class Deg { 
    public: 
     Deg() {} 
     Deg(int a) : d(a) {}   
     void operator()(double a) 
     { 
      cout << pow(a,d) << endl; 
     } 

    private: 
     int d; 
}; 

int 
main(int argc, char **argv) 
{ 
    Deg d = 2; 
    d(5); 
    d = 3; /* this shouldn't work, Deg doesn't have an operator= that takes an int */ 
    d(5); 
    return 0; 
} 

Sur la troisième ligne de la fonction principale, je suis un int à assigne un objet de classe Deg. Comme je n'ai pas de fonction operator=(int), j'ai pensé que cela échouerait certainement ... mais appelle le constructeur Deg(int a). Est-ce que les constructeurs contrôlent également l'assignation?

Répondre

18

C'est ce qu'on appelle la conversion de type implicite. Le compilateur cherchera à voir s'il y a un constructeur à changer directement du type que vous assignez au type que vous essayez d'assigner, et l'appelez. Vous pouvez arrêter de se produire en ajoutant le mot-clé explicit devant le constructeur que vous ne voulez pas être appelé implicitement, comme ceci:

explicit Deg(int a) : d(a) {}

+0

+1 pour – dimba

+3

explicite Au moins une entreprise que j'ai travaillé à la règle a eu « utilisation explicite tous les constructeurs à moins qu'il y ait une bonne raison de ne pas "parmi ses normes de codage". Cela permet d'éviter des situations potentiellement embarrassantes comme celle-ci. – Sean

+0

Je suppose que vous voulez dire sur tous les constructeurs qui peuvent être invoqués avec un seul argument :)? –

4

Juste pour clarifier la réponse de JonM:

Pour la ligne d = 3, un opérateur d'affectation est impliqué. 3 est implicitement convertie en Deg, comme l'a dit JonM, puis que Deg est affecté à d en utilisant l'opérateur d'affectation généré par le compilateur (qui, par défaut, effectue une affectation par membre). Si vous voulez éviter la cession, vous devez déclarer un opérateur d'affectation privée (et ne mettre en œuvre pas):

//... 
private: 
    Deg& operator=(const Deg&); 
}