Maison >développement back-end >C++ >Pourquoi `std::unique_ptr` échoue-t-il avec des types incomplets et comment puis-je y remédier ?

Pourquoi `std::unique_ptr` échoue-t-il avec des types incomplets et comment puis-je y remédier ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-08 01:29:161023parcourir

Why Does `std::unique_ptr` Fail with Incomplete Types, and How Can I Fix It?

Obstacle de type incomplet pour std::unique_ptr

L'utilisation de std::unique_ptr avec un type incomplet soulève des problèmes de compilation. Lors de l'utilisation de l'idiome pimpl avec std::unique_ptr, un code ressemblant à celui-ci peut déclencher les problèmes suivants :

class window {
  window(const rectangle& rect);

private:
  class window_impl; // defined elsewhere
  std::unique_ptr<window_impl> impl_; // compilation failure
};

Une erreur de compilation concernant un type incomplet est rencontrée, car std::unique_ptr attend une définition de type complète.

Dévoiler la cause profonde : la destruction Lacunes

Malgré la compatibilité attendue entre std::unique_ptr et les types incomplets, le problème vient de l'absence de déclaration de destructeur. Les constructeurs par défaut générés par le compilateur nécessitent une déclaration complète de la classe implémentée.

Pour remédier à ce problème, définissez explicitement un destructeur dans la classe externe, garantissant sa disponibilité lorsque la classe implémentée est complète :

class foo
{ 
    class impl;
    std::unique_ptr<impl> impl_;

public:
    foo(); // May require a default constructor defined elsewhere

    ~foo(); // Implement with an empty body or use "= default;"
};

Mises en garde concernant les constructeurs de modèles

Définir un constructeur de modèles complique les choses, même si le membre implémenté n'est pas initialisé :

template <typename T>
foo::foo(T bar) 
{
    // Compiler requires knowledge of impl_ destruction in case of exceptions
}

Restrictions au niveau de l'espace de noms

L'utilisation de std::unique_ptr avec des types incomplets dans la portée de l'espace de noms pose également des défis :

class impl;
std::unique_ptr<impl> impl_;

Le compilateur doit savoir comment détruire l'objet de durée statique. Un remède consiste à envelopper le std::unique_ptr dans une structure personnalisée avec un destructeur défini :

class impl;
struct ptr_impl : std::unique_ptr<impl>
{
    ~ptr_impl(); // Implement with an empty body
} impl_;

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn