Comment faire de-initialisation statique si le destructor a des effets secondaires et l'objet est accessible à partir d'un autre destructor l'objet statique?

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

Question

Il y a un simple et modèle bien connu pour éviter le fiasco d'initialisation statique, décrite dans article 10.13 du C ++ FAQ Lite .

Dans ce modèle standard, il y a un compromis fait en ce que soit l'objet construit ne fait jamais détruit (ce qui est pas un problème si le destructor n'a pas d'effets secondaires importants) ou l'objet statique ne peut pas en toute sécurité accessible depuis une autre le destructor de l'objet statique (voir section 10.14 du C ++ FAQ Lite ).

Alors, ma question est: Comment éviter le fiasco statique de-initialisation si un destructeur de l'objet statique a des effets secondaires importants qui doivent éventuellement se produire et l'objet statique doit être accessible par le destructor d'un autre objet statique ?


(Note: la FAQ-lite mentionne cette question reçoit une réponse FAQ 16,17 de C ++ FAQ: Questions fréquentes par M. Cline et G. et Lomow Je n'ai pas accès à ce livre, qui est. pourquoi je pose cette question à la place.)

Était-ce utile?

La solution

objets statiques fonctionnent comme des objets globaux sont garantis à détruire (en supposant qu'ils sont créés).

L'ordre de destruction est l'inverse de la création.
Ainsi, si un objet dépend d'un autre objet lors de la destruction, vous devez garantir qu'il est toujours disponible. Ceci est relativement simple que vous pouvez forcer l'ordre de destruction en vous assurant de l'ordre de la création est faite correctement.

Le lien suivant est sur le point singeltons mais décrit une situation similaire et sa solution:
Trouver C ++ initialisation statique des problèmes d'ordre

extrapolant au cas général de GLOBALS initialisés paresseux comme décrit dans la FAQ Lite nous pouvons résoudre le problème comme ceci:

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;
    }
}

Autres conseils

Tant que la destructor statique autre objet se dirige d'abord, vous êtes ok. Vous pouvez assurer en ayant l'autre objet se construit avant « objet A ». Tant que les deux objets sont déclarés dans la même unité de compilation, ils seront initialisés dans l'ordre où ils apparaissent dans la source, et dans l'ordre détruits opposé.

Si vous avez besoin que cela se produise dans toutes les unités de compilation, vous êtes hors de la chance. Mieux vaut pour les créer dynamiquement lors de l'exécution et les détruire à la fin de la principale, plutôt que ce qui les rend statique.

Il est un peu un hack mais j'ajouter quelques bools de statiques pour garder la trace de l'ordre de de l'initialisation Ensuite, l'objet qui finit dernier, le nettoyage ne même si elle est pas le propriétaire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top