Ich verstehe, was ein doppeltes Ausrufezeichen tut (oder ich glaube, ich verstehe), aber ich bin mir nicht sicher, wie es bei einem zufälligen Objekt definiert ist. Zum Beispiel im folgenden Codefragment:
%Vor%Woher weiß ich, welchen Wert das doppelte Ausrufezeichen haben wird? Mit anderen Worten, konvertiert es immer zu wahr? falsch? oder können Sie ein Verhalten dafür definieren, zum Beispiel eine Methode ausführen, um das Ergebnis zu bestimmen (wie kann das Objekt in dieser Situation handeln)? Ich bin etwas verwirrt über dieses Stück Code aufgrund all dieser Ausrufe Sachen weiter. Jede Erklärung ist willkommen.
Ich hoffe, ich war klar und danke.
a
ist ein Zeiger. In C ++ ist nullptr
als ungültiger Zeiger definiert. !pointer
verwandelt einen nullptr
Zeiger in true
und einen nicht nullptr
Zeiger in false
. !boolean
verwandelt true
in false
und false
in true
. Es wird immer funktionieren.
!(!a)
ist eine nützliche Methode, um darüber nachzudenken.
Betrachte es nicht als "doppeltes Ausrufezeichen", sondern stelle es als zwei getrennte Operatoren dar, von denen einer auf dem Ergebnis des anderen läuft.
Für alle primitiven Typen wird es "funktionieren". !a
entspricht a == 0
, also entspricht !!a
!(a == 0)
, was wiederum a != 0
entspricht.
Für benutzerdefinierte Typen wird es nicht kompiliert, wenn sie operator !
nicht überladen. Aber in diesem Fall könnte das Verhalten fast alles sein.
!!
ist kein einzelnes Token in C ++ und löst einfach den Operator !
zweimal.
Da a
ein Zeiger und kein Objekt des Klassentyps ist, kann !
nicht überladen werden. Es ist so definiert, dass true
zurückgegeben wird, wenn a
ein Nullzeiger und false
andernfalls ist.
Die zweite Anwendung von !
negiert einfach das Ergebnis der ersten !
.
Der Ausdruck !!a
entspricht a != 0
.
Der Code ist schrecklich kompliziert. In Wirklichkeit möchten Sie testen, ob die Methode getAssigment
erfolgreich ist und ob der zugewiesene Zeiger nicht null ist.
Der Code testet dies, wenn auch in einer verschlungenen Art und Weise, indem er die schwache Typisierung ausnutzt, anstatt zu versuchen, die Explicitness und C ++ starke Typisierung einzubeziehen. Als Konsequenz ist es kein idiomatisches C ++ und etwas schwieriger zu verstehen als nötig.
Verwenden Sie insbesondere nicht !!a
in C ++. Dies ist ein etabliertes Idiom in schwach typisierten Sprachen wie JavaScript, um einen Wert in einen booleschen Typ zu zwingen. Aber in C ++ ist dies nicht üblich.
Es ist nicht klar, was der Code tut, da hasSolution
nicht definiert oder verwendet wird. Ich vermute jedoch , dass der Code dem folgenden entspricht:
(Vor C ++ 11 müssen Sie 0
anstelle von nullptr
schreiben.)
Dieser Code zeigt jedoch immer noch ein schlechtes Design: Warum wird a
als Referenz übergeben? Warum ist es nicht der Rückgabewert? Schlimmer noch, a
wird nie benutzt, also unnötig. Wenn a
tatsächlich unnötig ist, sollte es komplett weggelassen werden. Wenn es notwendig ist, sollte es der Rückgabewert sein. Mit anderen Worten, der Prototyp von getAssignment
sollte wie folgt aussehen:
Und es sollte einfach wie folgt verwendet werden:
%Vor% Außerdem vermute ich, dass dieser Code dem rohen Zeiger a
tatsächlich Speicherbesitz zuweist. Dies wird in modernem C ++ dringend empfohlen . Verwenden Sie entweder keine Zeiger oder einen intelligenten Zeiger.
Es gibt kein "!!" Operator, also in der Tat entspricht die Aussage:
hasSolution =! (! a);
Zuerst wird der Operator! () für den Ausdruck "a" aufgerufen, dann wird ein anderer Operator! () für das Ergebnis aufgerufen. Im Falle unseres Codes ist "a" ein Zeiger auf Zuordnung. C ++ definiert einen Sonderfall für die Verwendung von operator! () Für einen Zeigertyp: Es gibt ein Bool zurück, das wahr ist, wenn der Zeiger Null ist und andernfalls false. Kurz gesagt, das gleiche wie der Ausdruck (a == 0). Das Aufrufen von operator! () Auf das Ergebnis von (! A), was ein bool ist, kehrt einfach das Ergebnis zurück, d. H. Gibt wahr zurück, wenn (! A) falsch und falsch ist, wenn (! A) wahr ist.
Zusammenfassend ergibt (!! a) dasselbe Ergebnis wie (a! = 0). Dies liegt daran, dass "a" ein Zeiger ist.
Tags und Links c++ boolean logical-operators