Wie statische de-Initialisierung tun, wenn die destructor Nebenwirkungen und das Objekt wird von einem anderen statischen Objekt Destruktor zugegriffen?

StackOverflow https://stackoverflow.com/questions/3143180

Frage

Es gibt eine einfache und bekannte Muster der statischen Initialisierung Fiasko, in Abschnitt 10.13 des C ++ FAQ Lite .

In diesem Standardmuster gibt es einen Kompromiss in dem machte entweder das konstruierte Objekt wird zerstört nie (was kein Problem ist, wenn der Destruktor nicht wichtig Nebenwirkungen hat) oder das statische Objekt nicht sicher von einem anderen zugegriffen werden statisches Objekt Destruktor (siehe Abschnitt 10.14 der C ++ FAQ Lite ).

Meine Frage ist also: Wie Sie das statische Deinitialisierung Fiasko vermeide, wenn ein statisches Objekt Destruktor wichtige Nebenwirkungen haben, die schließlich auftreten muß und das statische Objekt muss durch ein anderes statisches Objekt Destruktor zugegriffen werden ?


(Hinweis: der FAQ-lite erwähnt diese Frage in FAQ 16.17 von beantwortet C ++ FAQs: Häufig gestellten Fragen von M. Cline und und G. Lomow Ich habe keinen Zugang zu diesem Buch, das ist. warum ich diese Frage stellen, statt.)

War es hilfreich?

Lösung

Funktion statische Objekte wie globale Objekte sind garantiert zerstört werden (vorausgesetzt, sie erstellt werden).

Die Reihenfolge der Zerstörung ist die Umkehrung der Schöpfung.
Wenn also ein Objekt auf ein anderes Objekt während Zerstörung hängt müssen Sie garantieren, dass es nach wie vor zur Verfügung. Dies ist relativ einfach, wie Sie die Reihenfolge der Zerstörung, indem sie zwingen kann, dass die Ordnung der Schöpfung es richtig gemacht wird.

Der folgende Link ist über singeltons sondern beschreibt eine ähnliche Situation und ihre Lösung:
Finding C ++ statische Initialisierungsreihenfolge Probleme

zu dem allgemeinen Fall faul initialisierte Globals Rechnet man, wie in der FAQ beschrieben lite wir das Problem wie folgt lösen:

namespace B
{
    class B { ... };

    B& getInstance_Bglob;
    {
        static B instance_Bglob;
        return instance_Bglob;;
    }

    B::~B()
    {
         A::getInstance_abc().doSomthing();
         // The object abc is accessed from the destructor.
         // Potential problem.
         // You must guarantee that abc is destroyed after this object.
         // To gurantee this you must make sure it is constructed first.
         // To do this just access the object from the constructor.
    }

    B::B()
    {
        A::getInstance_abc();
        // abc is now fully constructed.
        // This means it was constructed before this object.
        // This means it will be destroyed after this object.
        // This means it is safe to use from the destructor.
    }
}
namespace A
{
    class A { ... };

    A& getInstance_abc()
    {
        static A instance_abc;
        return instance_abc;
    }
}

Andere Tipps

Solange das andere Objekt statische destructor läuft zuerst, du bist ok. Sie können dies gewährleisten, indem das andere Objekt vor „Objekt A“ erhalten aufgebaut ist. Solange beiden Objekte in derselben Übersetzungseinheit deklariert sind, werden sie in der Reihenfolge initialisiert werden sie in der Quelle erscheinen, und in umgekehrter Reihenfolge zerstört.

Wenn Sie diese über Übersetzungseinheiten hinweg geschehen, bist du kein Glück. Besser ist es, sie zur Laufzeit dynamisch zu erstellen und sie am Ende der Haupt zerstören, anstatt sie zu statisch zu machen.

Es ist ein bisschen wie ein Hack, aber ich würde einige statischen bools hinzufügen Spur in der Größenordnung von de Initialisierung halten dann das Objekt, das Enden bis zuletzt funktioniert die Sanierung auch wenn es nicht der Eigentümer ist.

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