Du meinst vermutlich NULL.

Das ist eine Makrodefinition aus alten C-Zeiten, die meistens einem void-Zeiger-cast auf Adresse 0 entsprechen wird, aber nicht muss.

Bei C++ nimmt man allerdings "nullptr":

https://en.cppreference.com/w/cpp/language/nullptr

"NULL" solltest du nur noch nutzen, wenn du es mit alter Software zu tun hast. Gewöhn dir am besten grundsätzlich "nullptr" an!

...zur Antwort

Das hängt viel weniger von der Bedingung ab, als du denkst, sondern viel mehr von der Anweisung, bzw. dem Anweisungsblock, der folgt.

Wenn du folgendes Snippet nimmst:

if (irgendwas) {
  wert = 123;
} else {
  wert = 456;
}

Dann wird jede moderne CPU (egal ob x86, ARM, oder sogar µC) daraus zwei CPU-Instruktionen zusammen bauen, die der Variablen den entsprechenden Wert zuweisen.

Wenn du hingegen diesen Inhalt im Anweisungsblock hast:

if (irgendwas) {
  foo();  
} else {
  bar();
}

Dann wird ein bedingter Sprung nötig werden, was auf modernen x86-CPUs ca. 2000 mal langsamer ist, als der Fall im vorherigen Snippet mit der bedingten Zuweisung einer Variablen.

Wie du siehst, macht die Bedingung an sich keinen Unterschied, das, was danach kommt, allerdings schon!

Aus diesem Grunde rate ich grundsätzlich allen Softwareentwicklern auch heutzutage Assembler zu lernen, und einen Disassembler in den Buildprozess einzubauen, um überhaupt mal zu sehen, was der Compiler so Tolles (oder oft auch weniger Tolles) tut.

Übrigens, was einen viel größeren Einfluss als eine boolesche Variable hat, ist die Reihenfolge des if- und else-Inhaltes.

Ab C++20 gibt es endlich die Attribute [[likely]] und [[unlikely]]. Vorher musste man sich mit compilerspezifischen Sonderlösungen auseinander setzen.

Aber ohne all das, sind folgende Beispiele sehr unterschiedlich performant!

Beispiel A:

if (fehlercode == 123) {
  reparieren();
} else {
  weitermachen();
}

Beispiel B:

if (fehlercode != 123) {
  weitermachen();
} else {
  reparieren();
}

Nur die Reihenfolge hat hier einen massiven Einfluss auf die Laufzeit, und kann an häufig wiederholten Stellen zum Flaschenhals werden.

Und noch ein Hinweis zu switch: Das ist in C und C++ leider höchst ineffizient gelöst, weshalb es sich eingebürgert hat an wirklich Performancekritischen Stellen, mit goto und lokalen Labels als Offset zu arbeiten. Das klingt jetzt schlimmer als es ist, vor allem für Anfänger, die gehört haben, dass "goto ja böse sei", aber für Profis sind ordentlich eingesettzte goto-Statements eine sehr elegante Lösung.

Naja, um bei solchen Dingen nicht raten zu müssen, schreibe dir einfach ein Skript, welches dir eine Funktion in einer Quelldatei kompiliert und die Objektdatei direkt danach wieder disassembliert!

Dann siehst du auf sehr einfache Weise ganz genau, was wann wie worin übersetzt und inwieweit optimiert wird.

Viel Spaß! :)

...zur Antwort

Der Destuktor von Stackobjekten wird automatisch am Ende des Gültigkeitsbereiches aufgerufen. (von Ausnahmen wie globalen Variablen mal abgesehen)

Hier ist mit einem Kommentar exakt markiert, wo der Destruktor aufgerufen wird:

void foo() {
  list<int> l;

  // mach was mit der Liste ...

  for (const i : l) {
    cout << i << endl;
  }

  // <- der Destruktor wird HIER aufgerufen!
}

Ein delete darfst du auf gar keinen Fall aufrufen, da die Variable ja nicht auf dem Heap liegt. Tust du es doch, wird dein Programm abstürzen!

Du solltest dich unbedingt mit Gültigkeitsbereichen und der Funktionsweise von Konstruktoren befassen! Das ist in C++ nämlich DAS Kernkonzept überhaupt, viel viel mehr noch, als in anderen Programmiersprachen.

Viel Erfolg beim Lernen! :)

...zur Antwort