„Fiasko“ der statischen Initialisierungsreihenfolge verhindern, C++

Lesezeit: 4 Minuten

„Fiasko der statischen Initialisierungsreihenfolge verhindern C
Eduard Rostomyan

Einmal las ich ein tolles Häufig gestellte Fragen zu C++ (Es ist wirklich gut!!) und lies das Thema darüber, wie das “Fiasko” der statischen Initialisierungsreihenfolge verhindert werden kann. Der Autor rät daher, die statischen Variablen in Funktionen zu verpacken, um so das “Fiasko” durch Beibehaltung der Erstellungsreihenfolge von Variablen zu verhindern. Aber das scheint mir ein unhöflicher Workaround zu sein. Meine Frage ist also, gibt es einen modernen, mehr an Mustern orientierten Weg, um dieses “Fiasko” zu verhindern, als das “statische Zeug” in Funktionen zu verpacken???

  • Der elegante Weg, ein Fiasko zu verhindern, besteht darin, niemals statische Objekte zu verwenden, die von irgendetwas abhängen.

    – Erorika

    23. April 2015 um 11:36 Uhr

  • Die FAQ berät über die Konstruieren Sie bei der ersten Verwendung Idiom. Ein bekanntes Muster für viele C++-Programmierer. Es ist einfach zu implementieren und noch einfacher zu verwenden. Ich verstehe nicht, was Sie mit “moderner, musterorientierterer Art” meinen.

    – Cassio Renan

    23. April 2015 um 11:42 Uhr

  • Siehe auch AddressSanitizerInitializationOrderFiasco.

    – jww

    11. Januar 2016 um 10:31 Uhr

Der moderne, eher musterorientierte Weg ist Globals gar nicht erst zu verwenden.

Es gibt keinen anderen Weg daran vorbei.

Sonst wäre es kein großes „Fiasko“!

  • Leider ist dies nicht realistisch. Es hilft nicht Tausenden von Paketen in einem typischen Repo oder der FTP-Site von GNU.

    – jww

    11. Januar 2016 um 10:32 Uhr

  • @jww: Die einzig vernünftige Alternative besteht darin, das zu tun, was das OP selbst in der Frage vorschlägt.

    – Leichtigkeitsrennen im Orbit

    11. Januar 2016 um 11:01 Uhr

  • Das ist eine falsche Wahl. Es verschiebt das Problem, sodass der Absturz im Destruktor auftritt; und kein Konstrukteur. Ich habe den Absturz im dtor hautnah erlebt, wenn ein Objekt zu früh verschwindet.

    – jww

    11. Januar 2016 um 13:09 Uhr


  • @jww Code mit diesem Problem hat schwerwiegende Abhängigkeitsprobleme und sollte umgestaltet werden.

    – Leichtigkeitsrennen im Orbit

    11. Januar 2016 um 13:32 Uhr

Meine Frage ist also, gibt es einen modernen, mehr an Mustern orientierten Weg, um dieses “Fiasko” zu verhindern, als das “statische Zeug” in Funktionen zu verpacken???

In den meisten Fällen können Sie Ihre “globalen” Daten in der Hauptfunktion deklarieren und sie bei Bedarf mithilfe der Abhängigkeitsinjektion weitergeben. Mit anderen Worten, haben überhaupt keinen statischen Zustand.

In der Praxis kann es Situationen geben, in denen statische Daten benötigt werden. Wenn keine Abhängigkeiten zu anderen Statiken bestehen, machen Sie die statischen Daten const/constexpr.

// smart pointer that implements the "Foo" release policy
class FooPointer
{
    static const FooPointer NullFoo; // does not depend on other static values
    /* ... */
};

Falls die statischen Variablen tun voneinander abhängen, packen Sie sie einfach in statische Funktionen:

// smart pointer that implements the "Foo" release policy
class FooPointer
{
    static const FooPointer& NullFoo(); // depends on other static values
    /* ... */
};

Zusammenfassen:

Die meisten (90 %? 99 %?) statischen/globalen/gemeinsam genutzten Daten sollten dort, wo sie verwendet werden, abhängigkeitsinjiziert und überhaupt nicht als statisch erstellt werden.

In den seltenen Fällen, in denen Statiken aus dem einen oder anderen Grund erforderlich sind und nicht von anderen Statiken abhängen, deklarieren Sie statische Variablen.

In dem sehr In seltenen Fällen, in denen Statiken statisch sein müssen und sie voneinander abhängen, wap sie in statische Methoden.

Als Faustregel gilt: Wenn Sie viele der zweiten und dritten Fälle haben, tun Sie nicht genug für den ersten.

Die üblichere Art, das Problem anzugehen, besteht darin, Statik wann immer möglich zu vermeiden – und noch mehr zwischen Objekten, die von der Bauordnung abhängen.

Konstruieren Sie dann Objekte in der erforderlichen Reihenfolge. Wenn wir zum Beispiel zwei Objekte x und y haben und die Konstruktion von y fehlschlägt, wenn x nicht konstruiert wurde, dann konstruieren Sie zuerst x und übergeben es dem Konstruktor (oder einem anderen Mitglied) von y)

 SomeObject x;
 SomeOtherObject y(x);

oder

 SomeObject *x = new SomeObject;
 SomeOtherObject y = new SomeObject(*x);   

(Beide oben nehmen den Konstruktor von an y erfordert eine Referenz).

Wenn Sie teilen müssen x und y zwischen Funktionen übergeben Sie sie einfach als Argumente an Funktionen.

Wenn Sie Statics verwenden müssen (d. h. Sie möchten nicht, dass überall übergebene Argumente eingegeben werden), machen Sie die Statics zu Zeigern und initialisieren Sie sie einmal (z. B. in main()).

//  all source files can use x and y via these declarations  (e.g. via a header file)

extern SomeObject *x;
extern SomeOtherObject *y;

//  definition in one source file only

SomeObject *x;
SomeOtherObject *y;

int main()
{
     x = new SomeObject;
     y = new SomeOtherObject(*x);

       // call other functions that use x and y.

     delete y;
     delete x;
}

Aber eigentlich ist es am besten, Statik möglichst zu vermeiden.

  • +1 Dies ist meiner Meinung nach ein besserer Ansatz als das Konstrukt für die Erstverwendungssprache. Eine mögliche Verbesserung beim Hochskalieren auf größere Projekte ist die Verwendung von Initialisierungs- und Zugriffsfunktionen (um den Zeiger auszublenden und zu bestätigen, dass die Initialisierung durchgeführt wurde) und die Gruppierung von Initialisierungen nach Bibliothek. Die Grundidee ist jedoch dieselbe: Übernehmen Sie die Kontrolle darüber, wann die Initialisierung und Bereinigung abgeschlossen ist, und überlassen Sie es nicht dem Zufall.

    – markh44

    28. April 2020 um 14:38 Uhr

923070cookie-check„Fiasko“ der statischen Initialisierungsreihenfolge verhindern, C++

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy