Frage

In C ++ Sie eine Variable in einem initialisieren if-Anweisung, etwa so:

if (CThing* pThing = GetThing())
{
}

Warum sollte man diese schlecht oder gut Stil in Betracht ziehen? Was sind die Vor- und Nachteile?

Ich persönlich mag diesen Stil, weil sie den Umfang der pThing variabel begrenzt, so dass es nie versehentlich verwendet werden, wenn es NULL ist. Aber ich mag es nicht, dass Sie dies nicht tun können:

if (CThing* pThing = GetThing() && pThing->IsReallySomeThing())
{
}

Wenn es ein Weg, um die oben genannten Arbeiten zu machen, bitte posten. Aber wenn das ist einfach nicht möglich, würde ich noch gerne wissen, warum.

Frage entlehnt von hier, ähnlichem Thema aber PHP.

War es hilfreich?

Lösung

Das Wichtigste ist, dass eine Erklärung in C ++ ist kein Ausdruck.

bool a = (CThing* pThing = GetThing()); // not legit!!

Sie können nicht beides tun, um eine Erklärung und Boolesche Logik in einer if-Anweisung, C ++ Sprache Spec erlaubt zwar entweder einen Ausdruck oder eine Erklärung.

if(A *a = new A)
{
    // this is legit and a is scoped here
}

Wie können wir wissen, ob ein zwischen einem Begriff und einem anderen in einem Ausdruck definiert ist?

if((A *a = new A) && a->test())
{
    // was a really declared before a->test?
}

Bite the Bullet und verwenden einen internen wenn. Die Bereichsregeln sind nützlich und Ihre Logik ist eindeutig:

if (CThing* pThing = GetThing())
{
    if(pThing->IsReallySomeThing())
    {
    }
}

Andere Tipps

Über die Vorteile:

Es ist immer empfehlenswert, Variablen zu definieren, wenn Sie zuerst sie benötigen, nicht vor einer Linie. Dies ist für eine verbesserte Lesbarkeit des Codes, da man sagen kann, was CThing ist ohne Scrollen und Suchen, wo sie definiert wurde.

Auch Umfang zu einer Schleife zu reduzieren / wenn Block, wird auf die Variable nach der Ausführung der Codeblöcke unreferenzierten wird, die es ein Kandidat für die Garbage Collection macht (wenn die Sprache unterstützt diese Funktion).

if (CThing* pThing = GetThing())

Es ist stillos , da im Inneren des if Sie einen Booleschen Ausdruck nicht bereitstellt. Sie bieten eine CThing*.

CThing* pThing = GetThing();
if (pThing != NULL)

Das ist eine gute Art.

Ein Grund, warum ich normalerweise nicht tun, weil der gemeinsamen Fehlers von einem verpassten ‚=‘ in einem bedingten Test. Ich benutze Flusen mit den Fehlern / Warnungen eingestellt diejenigen zu fangen. Es wird dann alle Zuordnungen innerhalb conditionals schreit über.

Nur ein FYI einige der älteren Microsoft C ++ compliers (Visual Studios 6 und .NET 2003 glaube ich) folgen nicht ganz die Scoping-Regel in einigen Fällen.

for(int i = 0; i > 20; i++) {
     // some code
}

cout << i << endl;

ich den Gültigkeitsbereich sein soll, aber das war / ist gültige Code. Ich glaube, es wurde als ein Merkmal ausgespielt, aber meiner Meinung nach ist es nur nicht eingehalten. Nicht an die Standards anhaftenden ist schlecht. Gerade als Web-Entwickler über IE und Firefox.

Kann jemand mit VS-Check und sehen, ob das noch gültig ist?

Das sollte funktioniert nicht in C ++ da obwohl es unterstützt Kurzschlussauswertung . Vielleicht Versuchen Sie nicht, die folgenden:

if ((CThing* pThing = GetThing()) && (pThing->IsReallySomeThing()))
{
}

err .. siehe Wesley Tarle Antwort

Sie können auch die Zuordnung in einem zusätzlichen Satz () umschließen die Warnmeldung zu verhindern.

Ich sehe, dass als eine Art gefährlich. Der folgende Code ist viel sicherer und die umschließenden Klammern noch den Umfang der pThing in der Art und Weise Sie wollen begrenzen.

Ich gehe davon aus GetThing () gibt manchmal NULL, weshalb ich in der if () Aussage, dass lustige Klausel setzen. Es verhindert, dass IsReallySomething () auf einen NULL-Zeiger aufgerufen wird.

{
    CThing *pThing = GetThing();
    if(pThing ? pThing->IsReallySomeThing() : false)
    {
    // Do whatever
    }
}

Beachten Sie auch, dass, wenn Sie C ++ Code schreiben Sie den Compiler Warnung über „=“ in einer bedingten Aussage machen wollen (das nicht Teil einer Erklärung ist) ein Fehler auf.

Es ist akzeptabel und eine gute Codierung Praxis. Doch die Menschen von einem Low-Level-Codierung Hintergrund kommt nicht würden wahrscheinlich nicht zustimmen.

So viele Dinge. Zu allererst nackten Zeiger. Bitte vermeiden, dass sie mit allen Mitteln. Verwenden Sie Referenzen, optional, unique_ptr, shared_ptr. Als letztes Mittel, schreiben Sie Ihre eigene Klasse, die sonst mit Zeiger Eigentums- und nichts beschäftigt.

Verwenden Sie einheitliche Initialisierung, wenn Sie C ++ 11 erfordern kann (C ++ 14 bevorzugt C ++ 11 Defekte zu vermeiden): - es vermeidet = vs == Verwirrung und es ist strenger auf die Argumente zu überprüfen, ob es irgendwelche <. / p>

if (CThing thing {})
{
}

Stellen Sie sicher, operator bool zu implementieren vorhersehbarer Umwandlung von CThing in bool zu bekommen. Doch bedenken Sie, dass andere Menschen den Code nicht lesen operator bool sofort sehen würde. Explizite Methodenaufrufe sind in der Regel besser lesbar und beruhigend. Wenn Sie C ++ 17 erfordern können, verwenden initializer Syntax.

if (CThing thing {}; thing.is_good())
{
}

Wenn C ++ 17 ist keine Option, verwenden Sie eine Erklärung über, wenn wie andere vorgeschlagen haben.

{
  CThing thing {};
  if (thing.is_good())
  {
  }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top