Frage

Insbesondere frage ich mich, welche davon sollte ich schreiben:

{
    shared_ptr<GuiContextMenu> subMenu = items[j].subMenu.lock();
    if (subMenu)
        subMenu->setVisible(false);
}

oder:

{
    if (items[j].subMenu.lock())
        items[j].subMenu.lock()->setVisible(false);
}

Ich bin keine Stil-Richtlinien folgen erforderlich. Nach der Optimierung glaube ich nicht, entweder Wahl einen Unterschied in der Leistung macht. Was ist in der Regel die bevorzugte Art und warum?

EDIT: die Art des Artikels [j] .subMenu ist boost :: weak_ptr. (Sperre) erzeugt ein shared_ptr aus ihm heraus. Es ist eigentlich ein mehrdeutiger Unterschied in den beiden Versionen oben, darüber, wie lange die temporäre Shared_ptr dauert, so wickelte ich meine zwei Beispiele in {Klammern} die Mehrdeutigkeit dort zu lösen.

War es hilfreich?

Lösung

Eine alternative Methode:

if(shared_ptr<GuiContextMenu> subMenu = items[j].subMenu.lock()) {
    subMenu->setVisible(false);
}
//subMenu is no longer in scope

Ich gehe davon aus subMenu ist ein weak_ptr, wobei in diesem Fall Ihre zweite Methode zwei Provisorien erstellt, die möglicherweise oder nicht ein Problem sein könnten. Und Ihre erste Methode fügt eine Variable zu einem größeren Umfang, als es muss. Persönlich versuche ich zu vermeiden Zuweisungen innerhalb if Aussagen, aber dies ist einer der wenigen Fälle, in denen ich das Gefühl, seine nützlicher als die Alternativen.

Andere Tipps

In dieser spezielle Fall , Sie sollte wirklich die Version mit den temporären Variablen verwenden. Der Grund dafür ist nicht die Leistung, sondern Korrektheit - im Grunde, Sie sind nicht garantiert, dass die beiden x.lock() Anrufe denselben Wert zurückgeben (zB wenn ein anderer Thread gibt die letzte starke Referenz auf das Objekt nur zwischen den beiden Anrufen.). die starke Referenz in der temporären Variablen Durch das Halten, stellen Sie sicher, es wird nicht verschwinden.

Anders als das:

  • die Compiler kann in der Regel Funktionsaufrufe nicht optimieren, es sei denn sie beweisbar Nebeneffekt frei sind (dies ist schwer zu tun, aber Attribute können Hilfe) oder inlined. In diesem Fall hat der Anruf Nebenwirkungen.

  • Provisorien verwendet, kann zu kürzeren, lesbaren und wartbare Programmen führen (z. B. im Fall eines Fehlers, Sie beheben es an einem Ort)

Ich glaube, Sie haben Recht zu jeder Wahl nicht anders nach der Optimierung zu sein.

Persönlich würde ich eine neue Variable deklarieren, wenn sie den Code besser lesbar macht, wie wenn Sie Anrufe sind verketten, oder setzen Funktionsaufrufe innerhalb Funktionsaufrufe. Solange es wartbar ist und der Code erreicht die gleiche Wirkung ohne Geschwindigkeitsdifferenz, es läuft alles auf lesbaren Code nach unten.

Edit:

mmyers kaufte einen guten Kommentar auf. Ja, seien Sie vorsichtig über lock() zweimal anrufen, als nur einmal im Gegensatz zu. Sie werden unterschiedliche Wirkungen haben, abhängig von der jeweiligen Implementierung.

Die Wahl ist im Wesentlichen bis zu Ihnen, aber die grundlegende Sache, die Sie achten sollten, ist Wartbarkeit.

Wenn der Rückgabewert ist etwas anderes, dass ein boolean, es zu einem Zwischen Variablen zuweisen kann oft vereinfachen debuggen. Zum Beispiel, wenn Sie die folgenden Schritt über:

if( fn() > 0 ) ...

alles, was Sie wissen, nachdem die Tatsache war, dass die Funktion einen Wert entweder weniger zurück als Null ist, oder null oder mehr. Auch wenn der Rückgabewert falsch wäre, kann der Code noch zur Arbeit erscheinen. Zuweisen es zu einer Variablen, die in Ihrem Debugger kontrolliert werden können, ermöglicht es Ihnen, ob der Rückgabewert zu bestimmen, wurde erwartet.

Wenn die Rückkehr boolean ist, ist der tatsächliche Wert vollständig implizit durch den Code fließen, so dass es weniger kritisch ist; jedoch unter Codepflege können Sie feststellen, später Sie dieses Ergebnis benötigen, so dass Sie es sich zur Gewohnheit, kann in jedem Fall entscheiden zu machen.

Auch wenn der Rückgabewert boolean ist, ist eine andere Frage zu prüfen, ob die Funktion Nebenwirkungen erforderlich ist, und ob dies durch Kurzauswertung beeinträchtigt werden. Zum Beispiel in der Aussage:

if( isValid && fn() ) ...

wird die Funktion nie aufgerufen ist isValid falsch ist.

Die Umstände, unter denen der Code könnte durch den unvorsichtigen Programmierer unter Wartung gebrochen werden (und es ist oft die weniger erfahrenen Programmierer, die die Wartungsaufgaben bekommen) sind viele, und wahrscheinlich am besten vermieden werden.

In diesem speziellen Beispiel, ich glaube, es hängt davon ab, was lock() tut. Ist die Funktion teuer? Könnte es zurückgeben jedes Mal verschiedene Dinge die Funktion aufgerufen wird (es könnte einen Zeiger zum ersten Mal und NULL zum zweiten Mal zurück)? Gibt es einen anderen Thread ausgeführt wird, dass zwischen den beiden Anrufen zu lock() verschachteln können?

Für dieses Beispiel müssen Sie das Verhalten von lock() und den Rest des Codes zu verstehen, eine intelligente Entscheidung zu treffen.

ziehe ich die erste die meiste Zeit, weil sie den Code klar und leicht zu lesen macht daher weniger anfällig für Fehler. Zum Beispiel vergessen haben, eine Klammer an diesem zweiten Beispiel :) In diesem Fall würde tatsächlich, ich wahrscheinlich tun, was Sie im zweiten Beispiel haben jedoch, wenn ich das Untermenü mehr als ein paar Mal verwenden, musste ich mit dem ersten gehen würde den Code leichter zu lesen. Was die Leistung, was ich in der Lage jeder vernünftige Compiler, dass optimieren würde (was wahrscheinlich ist, warum Sie keinen Unterschied in der Leistung gesehen haben).

Auch als mmyers wies darauf hin, dass hängt auch davon ab, was sperren () der Fall ist. Im Allgemeinen, wenn es eine einfache Getter-Methode oder so etwas wie das ist, werden Sie in Ordnung sein.

Was auch immer Sie bevorzugen. Für mich hängt es davon ab, wie viel werde ich es verwenden; für zwei Linien, vielleicht schreibe ich es einfach beide Male aus, während ich eine Variable erstellen, wenn ich es verwenden. Allerdings sind Sie derjenige, der höchstwahrscheinlich diesen Code zu pflegen und weiter es zu betrachten, so verwenden, was für Sie arbeitet. Natürlich, wenn Sie bei einem Unternehmen mit einer Codierung Richtlinie sind, folgen.

Ich denke, der bevorzugte Stil ist, was Stil, den Sie denken, macht den Code besser lesbar und wartbar. Wenn Sie ein Team von mehr als einem, der einzigen anderen Überlegung sind, ist, dass es in der Regel eine gute Idee für alle den gleichen Stil, wieder für die Lesbarkeit zu übernehmen und die Wartung erleichtern.

In diesem Fall denke ich, Sie die temporären verwenden sollten. Selbst wenn Sie die Implementierung .lock () wissen, ist kostengünstig, kann das ändern. Wenn Sie Anrufsperre nicht brauchen () zweimal, nicht. Der Wert hier ist, dass es den Code aus der Umsetzung der Sperre abkoppelt (). Und das ist eine gute Sache im Allgemeinen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top