2010-02-20 5 views
7

Ich dachte, dass Konstruktoren die Initialisierung und Operator = Funktionen Kontrolle Zuordnung in C++ steuern. Warum funktioniert dieser Code?Zuweisung vs Initialisierung in 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; 
} 

In der dritten Zeile der Hauptfunktion, ich bin ein int auf ein Objekt der Klasse Deg zuweisen. Da ich keine operator=(int) Funktion habe, dachte ich, dass dies sicherlich fehlschlagen würde ... aber stattdessen ruft der Deg(int a) Konstruktor auf. Beherrschen Konstruktoren auch die Zuweisung?

Antwort

18

Dies wird als implizite Typumwandlung bezeichnet. Der Compiler sucht nach einem Konstruktor, der direkt von dem Typ, den Sie zuweisen, zu dem Typ wechselt, den Sie zuweisen möchten, und ruft ihn auf. Sie können durch Hinzufügen des explicit Schlüsselwort vor dem Konstruktor es nicht passiert stoppen würden Sie nicht implizit genannt werden möchte, wie folgt aus:

Für die:

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

+0

+1 für explizite – dimba

+3

Mindestens eine Firma, die ich gearbeitet habe in die Regel hatte „verwenden explizit auf alle Konstrukteure, es sei denn, es gibt einen guten Grund, nicht zu seinen Kodierungsstandards zu gehören. Das hilft, potenziell verwirrende Situationen wie diese zu vermeiden. – Sean

+0

Ich nehme an, Sie meinen auf alle Konstruktoren, die mit einem einzigen Argument aufgerufen werden können :)? –

4

Gerade JonM Antwort zu klären Zeile d = 3, ein Zuweisungsoperator ist beteiligt. 3 wird implizit in eine Deg konvertiert, wie JonM sagte, und dann Deg ist zu d mit dem Compiler-generierten Zuweisungsoperator zugewiesen (die standardmäßig eine Member-weise Zuordnung). Wenn Sie Zuordnung verhindern mögen, müssen Sie einen privaten Zuweisungsoperator erklären (und es nicht implementieren):

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