243 votes

std::unique_ptr avec un type incomplet ne compilera pas

J'utilise le pimpl-idiom avec 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, j'obtiens une erreur de compilation concernant l'utilisation d'un type incomplet, à la ligne 304 dans <memory> :

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

Pour autant que je sache, std::unique_ptr devrait pouvoir être utilisé avec un type incomplet. S'agit-il d'un bogue dans libc++ ou est-ce que je fais quelque chose de mal ici ?

1 votes

Lien de référence pour les exigences de complétude : stackoverflow.com/a/6089065/576911

1 votes

Un pimpl est souvent construit et non modifié depuis. J'utilise habituellement un std::shared_ptr<const window_impl>

0 votes

Relié : J'aimerais beaucoup savoir pourquoi cela fonctionne dans MSVC, et comment l'empêcher de fonctionner (afin de ne pas casser les compilations de mes collègues de GCC).

2voto

Ce n'est peut-être pas la meilleure solution, mais parfois vous pouvez utiliser partagé_ptr à la place. Bien sûr, c'est un peu exagéré, mais... comme pour unique_ptr, je vais peut-être attendre 10 ans de plus jusqu'à ce que les fabricants de standards C++ décident d'utiliser lambda comme suppresseur.

Un autre aspect. Selon votre code, il se peut qu'au moment de la destruction de la fenêtre_impl, celle-ci soit incomplète. Cela pourrait être la raison d'un comportement non défini. Voir ceci : Pourquoi, en réalité, la suppression d'un type incomplet est un comportement indéfini ?

Donc, si possible, je définirais un objet très basique pour tous vos objets, avec un destructeur virtuel. Et c'est presque bon. Vous devez juste garder à l'esprit que le système appellera le destructeur virtuel pour votre pointeur, donc vous devez le définir pour chaque ancêtre. Vous devez également définir la classe de base dans la section héritage comme une classe virtuelle (cf. ce pour plus de détails).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X