2010-08-06 6 views
10

Ich habe eine Klasse wie diese:Warum wird mein überladener C++ - Konstruktor nicht aufgerufen?

class Test{ 
public: 
    Test(string value); 
    Test(bool value); 

}; 

Wenn ich ein Objekt wie folgt erstellen:

Test test("Just a test..."); 

Der Bool Konstruktor aufgerufen wird!

Wer weiß warum?

Dank

+0

C++ nicht Methoden, btw, nur Member-Funktionen. Außerdem redest du hier über Konstrukteure. –

+0

Wow, ich lief heute genau auf dasselbe Problem ein! – Milan

Antwort

18

Die Art der "Just a test..."const char * ist, die entweder bool oder std::string implizit konvertiert werden können. Da std::string kein eingebauter Typ ist, wird const char * s in bool konvertiert. Sie können dies verhindern, indem Sie explizit die const char * zu einer std::string Umwandlung:

Test test(std::string("Just a test...")); 
+2

Die Lösung ist richtig, aber die Erklärung ist nicht ganz korrekt. Sie können * implizit von 'const char *' in 'std :: string' konvertieren (über einen der Konstruktoren von' std :: string'). Es ist nur, dass die Bool-Konvertierung bevorzugt wird. –

+0

Ich werde diese Änderung machen - danke! –

+1

"Nur ein Test ..." ist kein Zeichen *. In C++ ist es char const []. –

4

Die Art der "Just a test..."const char* ist. Es gibt eine eingebaute Konvertierung von Zeigern zu bool, die gegenüber der nicht eingebauten Konvertierung von const char* zu std::string bevorzugt ist.

Der Grund, dass die Bool-Konvertierung bevorzugt wird, ist, weil std::string, während Teil der Standardbibliothek, kein integrierter Typ wie Ganzzahlen, Zeiger und booleans ist. Es verhält sich wie jede andere Klasse und daher werden seine Konvertierungskonstruktoren nur nach Konvertierungen in integrierte Typen berücksichtigt.

8

Dies ist eine bekannte C++ - Störung.

Ihr Zeichenfolgenliteral hat den Typ von Chat const []. Sie haben zwei Konstrukteurs bekam, Umwandlung Sequenzen aus char const [] wie folgt aussehen Test:

1) char const [] -> char const * -> bool

2) char const [] -> char const * -> Std :: String

1) ist eine integrierte Standardkonvertierung, während 2) ist eine benutzerdefinierte Konvertierung. Integrierte Konvertierungen haben Vorrang vor benutzerdefinierten Konvertierungen. Daher wird Ihr String-Literal leichter in bool konvertiert als in std :: string.

0

Eine Möglichkeit ist eine Variable vom Typ std :: string zu erstellen und die Variable in geben:

std::string test = "TEST"; 
A a(test); 

diese Weise wird die Art als std::string explizit es an den Konstruktor wird standardmäßig nicht die bool definiert akzeptiert

3

Eine Möglichkeit, dieses Problem zu umgehen, besteht darin, einen anderen Konstruktor bereitzustellen, der ein const char * verwendet und dann explizit in eine std :: string konvertiert.

1

Wenn Sie einen Konstruktor (insbesondere mehrere Konstruktoren) haben, der nur ein einziges Argument enthält, kann es sinnvoll sein, sie als "explizit" zu deklarieren, um diese Art von Überraschungen zu vermeiden. Dies zwingt den Benutzer der Klasse dazu, sicherzustellen, dass er dem Konstruktor, den er verwenden möchte, den richtigen Typ gibt, und verhindert, dass diese impliziten Typumwandlungen hinter dem Benutzer ausgeführt und versteckt werden, um Fehler zu finden.

http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=15&rll=1

In C++ 0x, dies Umwandlung Betreiber erweitert wurde das gleiche Problem zu verhindern

http://www2.research.att.com/~bs/C++0xFAQ.html#explicit-convertion