Maison >développement back-end >C++ >Pourquoi `std::unique_ptr` échoue-t-il avec des types incomplets dans Pimpl Idiom ?

Pourquoi `std::unique_ptr` échoue-t-il avec des types incomplets dans Pimpl Idiom ?

DDD
DDDoriginal
2024-12-13 05:01:11456parcourir

Why Does `std::unique_ptr` Fail with Incomplete Types in Pimpl Idiom?

std::unique_ptr et types incomplets : un examen plus approfondi

Considérez l'idiome Pimpl employant std::unique_ptr:

class window {
  window(const rectangle& rect);

private:
  class window_impl; // defined elsewhere
  std::unique_ptr<window_impl> impl_; // won't compile
};

Cependant, une erreur de compilation survient en raison d'un type:

"Application invalide de 'sizeof' à un type incomplet 'uixx::window::window_impl'"

Traditionnellement, std::unique_ptr est compatible avec les types incomplets. Alors, où se situe le problème ?

Le nœud du problème : la destruction

La clé réside dans la destruction. Si pimpl est utilisé avec unique_ptr, le destructeur doit être déclaré explicitement :

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

public:
    foo(); // Constructor may need external definition

    ~foo(); // Implement (braceless or with = default;) once impl is complete
};

Sinon, le compilateur génère un destructeur par défaut nécessitant une déclaration complète de foo::impl.

Problèmes de modèles et instances de durée statique

Avec les constructeurs de modèles, des complications surviennent même si le Le membre impl_ n'est pas construit :

template <typename T>
foo::foo(T bar) {
    // Compiler requires knowledge of impl_ destruction at compile time!
}

De plus, l'utilisation de unique_ptr avec des types incomplets dans la portée de l'espace de noms échoue :

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

Le compilateur doit savoir comment détruire cet objet de durée statique. Une solution de contournement consiste à définir un type personnalisé :

class impl;
struct ptr_impl : std::unique_ptr<impl> {
    ~ptr_impl(); // Implement (empty body) elsewhere
} 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