Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

C++ : un nouveau débat technique lancé par Herb Sutter
Qui relance les questions "Guru of the Week" suite à la sortie de la norme C++11

Le , par gbdivers

0PARTAGES

1  0 
C'est une source d'information que les anciens connaissent bien. Guru of the Week (GotW) est un site créé et alimenté par Herb Sutter entre 1997 et 2003. Le principe est simple : une question technique est posée et les lecteurs interviennent pour répondre à la question en essayant de faire le tour de toutes les difficultés techniques qui pourraient apparaître. Cette discussion aboutie à une analyse en profondeur de la problématique posée. Ces questions et réponses ont eu tellement de succès que Herb Sutter a publié plusieurs ouvrages pour regrouper et compléter ces analyses : Exceptional C++ et More Exceptional C++.

Ces ouvrages restent très intéressants à lire pour celui qui veut progresser en C++, mais avec la sortie du C++11, il commençait à devenir nécessaire de refaire le point en prenant en compte la nouvelle norme. Depuis peu, Herb Sutter a donc relancé les GotW sur son blog, Sutter’s Mill. La nouvelle série de questions a repris en commençant avec le numéro 100. Ce week-end, Herb Sutter a publié un nouveau GotW numéro 104. Voici un résumé de la problématique qui est soumise :

Voici un code classique que l'on retrouve régulièrement dans beaucoup de projets.
Code : Sélectionner tout
widget* load_widget( widget::id desired );
Questions :
  • Qu'est-ce qui ne va pas avec le type de retour et que faudrait-il utiliser comme type de retour à la place ?
  • Vous ne souhaitez pas forcément modifier tout votre code existant pour être compatible avec le nouveau type de retour. Comment la compatibilité avec le code ancien sera-t-elle conservée ?


Les solutions proposées doivent évidemment tenir compte de la nouvelle norme. Pour vous aider un peu, cette question est notée avec une difficulté de 5/10 et est dans la série des pointeurs intelligents.

Sans aller voir les réponses proposées sur le site, sauriez-vous répondre à ces questions et être aussi bon que les lecteurs de Herb Sutter ?
Connaissiez-vous les Guru of the Week et les avez-vous déjà lu ?

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de Klaim
Membre expert https://www.developpez.com
Le 23/04/2012 à 12:12
J'ai repondu hier directement sur le site.
1  0 
Avatar de gbdivers
Inactif https://www.developpez.com
Le 23/04/2012 à 12:36
Citation Envoyé par Klaim Voir le message
J'ai repondu hier directement sur le site.
Ton analyse est très intéressante. En voici un petit résumé pour ceux qui maîtrise pas l'anglais :

Klaim pose la question de qui possède la responsabilité de la destruction de l'objet créé. Il distingue donc 3 possibilités :
  • la factory possède la responsabilité de détruire elle-même les objets qu'elle crée. Dans ce cas, un pointeur nu widget*, qui ne transmet aucune responsabilité, est indiqué.
  • la factory partage la responsabilité de la destruction de l'objet. Chaque utilisateur partage cette responsabilité et l'utilisation de shared_ptr<widget> est indiquée dans ce cas.
  • la factory n'a pour seule responsabilité que de créer l'objet, pas de le détruire. Elle donne donc la totalité de la responsabilité à l'utilisateur et il faut alors utiliser un unique_ptr<widget> dans ce cas.


On voit ici qu'il y a plusieurs solutions à un même problème. La "bonne" solution peut donc dépendre des contraintes et besoins que l'on a. Une analyse de la responsabilité de la durée de vie de l'objet est intéressante pour optimiser l'utilisation des pointeurs intelligents.

Que pensez-vous de l'intervention de Klaim et des questions qu'il soulève ?

JolyLoic pose également une question intéressante. Il retourne le problème et fait la remarque suivante :

Lorsque l'on rencontre un pointeur nu, il peut s'agir :
  • d'un objet dont la durée de vie est gérée par unique_ptr, le pointeur nu étant alors un simple pointeur sans responsabilité ;
  • d'une syntaxe ancienne, dont on n'a pas d'information sur qui possède la responsabilité de la durée de vie.

On se retrouve alors à se poser la question suivante : doit-on détruire l'objet manuellement (second cas) ou laisser la responsabilité à d'autre (premier cas) ?
JolyLoic propose donc d'ajouter un autre type de pointeur, qui prendrait clairement en charge le premier cas (donc un pointeur sans responsabilité pour un objet géré par un unique_ptr)

Dans vos propres codes, comment distinguer vous les deux cas d'utilisation des pointeurs nus et éviter de détruire manuellement des objets gérés par unique_ptr ?
1  0 
Avatar de Flob90
Membre expert https://www.developpez.com
Le 25/04/2012 à 15:27
@xbretzel: Et quand tu fais
Code : Sélectionner tout
1
2
int a;
Ce n'est pas le langage qui s'occupe de a ? Meme en C ? D'ailleurs dans
Code : Sélectionner tout
1
2
int* a = new int;
Tu n'es pas responsable de a au sens propre, mais de l'objet pointé par a, cad *a.

Quand on parle de responabilité de la durée de vie, la question n'est pas de savoir si c'est le langage ou le programmeur qui s'occupe de ca, mais surtout où le faire ?

Ensuite en C++ on utilise des capsules RAII qui transfert ca au langage, c'est nécessaire en particulier à cause des exceptions. En C il n'y a pas d'excpetion, cependant la gestion propre des erreurs et des allocations dynamique n'en est pas plus simple (goto pour faire du RAII entre autre).

Ensuite vient une question de "verbosité" que se pose Loic Joly. Le langage nous permet d'écrire différentes capsule (*) qui indique clairement si l'objet doit être détruit par l'appelant, si la fonction qui l'a crée s'occupe déjà de le détruire (**) ou enfin si ils ont besoin de pouvoir le détruire les deux. Ainsi Loic remarque qu'il manque une capsule pour dire : "la fonction s'occupe déjà de le détruire" (***).

(*) Si il existe assez de capsule, alors le besoin de pointeur nue dans le code métier peut totalement disparaitre. De même que le besoin de new/delete (toujours dans le code métier) avec les fonctions de création (make_shared,make_unique).

(**) Dans le cas où il peut ne pas y avoir d'objet retourné, sinon une référence me semble plus indiqué. D'ailleurs je pense qu'en terme d'utilisation, std::unique_ptr et les références doivent passer devant std::shared_ptr et une éventuelle nouvelle capsule.

(***) Dans un monde idéal sans se préoccuper "d'ancien code" ca ne serait pas nécessaire : pointeur nue = pas de responsabilité.
1  0 
Avatar de mitkl
Membre éprouvé https://www.developpez.com
Le 22/04/2012 à 19:49
Connaissiez-vous les Guru of the Week et les avez-vous déjà lu ?

Oui, depuis peu mais je n'ai jamais lu ceux qui précèdent le 100ème.

Sans aller voir les réponses proposées sur le site, sauriez-vous répondre à ces questions et être aussi bon que les lecteurs de Herb Sutter ?

Non pas directement mais de mémoire le 103ème faisait la distinction entre unique_ptr et shared_ptr et que le 104ème s'intitule "Smart Pointers part 2", la réponse doit donc être dans les pointeurs intelligents.
0  0 
Avatar de LittleWhite
Responsable 2D/3D/Jeux https://www.developpez.com
Le 23/04/2012 à 14:15
Bonjour,

Si la responsabilité n'est pas à nous de détruire le pointeur (cas de la factory, si j'ai suivi), alors il faudrait que le destructeur soit privé (ou protected )
0  0 
Avatar de gbdivers
Inactif https://www.developpez.com
Le 23/04/2012 à 14:19
Citation Envoyé par LittleWhite Voir le message
Bonjour,

Si la responsabilité n'est pas à nous de détruire le pointeur (cas de la factory, si j'ai suivi), alors il faudrait que le destructeur soit privé (ou protected )
Sauf que widget* n'est pas une variable membre (d'ailleurs, load_widget n'a pas besoin d'être une classe ou une fonction membre), donc pas de notion de public ou private ici.
Une petite révision du design pattern factory ? http://come-david.developpez.com/tut...e=Fabrique#LIV
0  0 
Avatar de LittleWhite
Responsable 2D/3D/Jeux https://www.developpez.com
Le 23/04/2012 à 14:51
Bah, je parlais surtout d'une classe qui gérerai tous les widgets.
Genre, vous charger le widget, le pointeur est gardé dans une "banque" et une copie du pointeur est renvoyé. Mais oui, j'imagine que l'on revient dans le cas de la variable membre ou similaire.
Pour la Factory, je sais mais je ne voulais pas dire un mot interdit
0  0 
Avatar de Klaim
Membre expert https://www.developpez.com
Le 23/04/2012 à 15:15
Merci gbdivers pour la traduction, j'avais pas le courage.

Pour la solution de JolyLoic je pense qu'avoir un smart pointer qui indique clairement que l'objet est juste référencé (ref_ptr?) mais pas managé par l'utilisateur serait une aide surtout pour totalement suprimer la possibilité d'un delete sur le pointeur (hors .get() qui est facilement trouvable).
0  0 
Avatar de bountykiler
Membre régulier https://www.developpez.com
Le 23/04/2012 à 22:47
Bon ben voilà, j'ai répondu à mon tour sur le blog

(En gros, mon idée est de créer une classe owner_ptr, laquelle se chargerai de garder l'ownership de la même manière que ce que fait un unique_ptr, mais qui autoriserait le partage de ce dernier via les weak_ptr.)
0  0 
Avatar de Klaim
Membre expert https://www.developpez.com
Le 24/04/2012 à 3:46
Je ne vois pas bien la difference avec un shared_ptr. Et aussi ca serait super couteux par rapport a un pointeur qui ne fait qu empecher l utilisateur de faire un delete...
0  0