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!