2013-05-08 20 views
10

Ist es möglich, das Verhalten von if() so dass sich ändern:C++ ‚Überlastung‘ der if() Anweisung

class Foo { 
    int x; 
}; 

Foo foo; 
if(foo) 

nur geht, wenn der Wert von x ist etwas anderes als Null? oder ...

Wäre eine explizite benutzerdefinierte Typumwandlung zu int funktionieren/wäre das ein geeigneter Ansatz? oder ...

Ist es am besten, etwas wie if(foo.getX()) zu tun?

+4

Wenn Sie dies in einer C++ 03 Kontext benötigen, können Sie in den sicheren Bool Idiom aussehen: http://www.artima.com/cppsource/safebool .html – Yuushi

Antwort

22

Sie können Ihr Objekt in einen booleschen Wert umwandeln, indem operator bool() definieren:

explicit operator bool() const 
{ 
    return foo.getX(); 
} 

Das explicit Schlüsselwort verhindert implizite Konvertierungen von Foo zu bool. Wenn Sie beispielsweise foo versehentlich in einen arithmetischen Ausdruck wie foo + 1 eingeben, könnte der Compiler diesen Fehler erkennen, wenn Sie operator bool() als explicit deklarieren, andernfalls wird foo in bool konvertiert, auch wenn dies nicht beabsichtigt ist.

Im Allgemeinen, Elementfunktionen der Form

operator TypeName() 

(mit optionalen explicit und const Qualifier) ​​sind Umwandlungsoperator. Sie können Ihre Klasse auf einen beliebigen Typ umwandeln, der von TypeName angegeben wird. In der anderen Richtung, Konstrukteure mit einem Argument können Sie jede Art Ihrer Klasse werfen:

class Foo { 
    Foo(int x); // convert int to Foo 
    operator bool() const; // convert Foo to bool 
    int x; 
}; 

Diese implizite Conversions für Ihre Klasse definiert. Der Compiler versucht diese Konvertierungen wenn möglich zu übernehmen (wie bei eingebauten Datentypen, z. B. 5 + 1.0). Sie können sie als explicit deklarieren, um unerwünschte implizite Konvertierungen zu unterdrücken.

+7

Es explizit zu machen ist wahrscheinlich besser. – chris

+1

Sie ** möchten ** definitiv dieses explizit markieren, es sei denn, Sie möchten Leuten erlauben, Dinge wie '! MyClass' zu tun. – templatetypedef

11

können Sie einen Operator definieren, das Objekt zu bool

class Foo 
{ 
    int x; 
public: 
    operator bool() const 
    { 
    return x > 0; 
    } 
}; 

Aber diese unbeabsichtigten Folgen zu bool wegen impliziter Konvertierungen haben zu konvertieren, wenn Sie Platz nicht die Umwandlung wünschen zu nehmen. Zum Beispiel

int x = 42 + Foo(); 

C++ 11 löst dieses Problem, indem Sie den Konvertierungsoperator als explicit, zu erklären, die dann nur implizite Konvertierungen in bestimmten Kontexten, wie innerhalb einer if Anweisung ermöglicht.

explicit operator bool() const // allowed in C++11 

Jetzt

int x = 42 + Foo(); // error, no implicit conversion to bool 
int x = 42 + static_cast<bool>(Foo()); // OK, explicit conversion is allowed