Citation:
Envoyé par
koala01
Justement, tu auras beaucoup plus facile à garder l'homogénéité de la chose en ne transmettant le "owner" que sous la forme de pointeur!
Autrement, tu vas devoir fournir le choix dans ton constructeur, quelque chose de proche de
Code:
1 2 3 4
| Class MaClass{
public:
MaClass( /* je mets quoi ici ??? */ owner);
}; |
Tu me permettras de me souvenir avoir entendu cet argument contre les std::string et std::vector, n'avoir pas été convaincu alors et de le considérer comme encore moins valable de nos jours, l'expérience ayant confirmé sa faible valeur.
Citation:
Même si make_unique fait son apparition, on en restera sur le fait que, quoi qu'il advienne, un constructeur prenant un unique_ptr tend à violer la loi de Demeter dés que le pointeur sous-jacent est déjà géré par ailleurs ;)
J'ai jamais trop accepté la loi de Demeter comme bonne. Où plutôt, si le principe sous-jacent est bon, l'appliquer au niveau de la classe est inutilement restrictif, ne pas considérer la nature des classes est absurde et son application mécanique -- comme l'application mécanique de tout principe de conception, mais bon quand on appelle son principe une loi, ça commence déjà mal -- m'a toujours semblé tenir du fétichisme. Demeter entre modules métiers, ça me semble bien. Demeter entre une classe métier et une classe technique, non. Si utiliser unique_ptr<> dans une interface est contraire à la loi de Demeter, ça ne risque que de me conforter dans mon opinion que sa formulation est nuisiblement restrictive.
Citation:
Envoyé par
koala01
j'ai des réticences à les exposer à partir du moment où ils sont manipulé au sein d'une classe, parce que ca a tendance à exposer des détails d'implémentation à l'utilisateur au sens de la loi de Déméter.
Je me fous de comment c'est géré à l'intérieur. Les unique_ptr dans l'interface définissent une interface, pas comment ce doit être géré à l'intérieur (même s'ils sont bien pratiques pour ça aussi).
Citation:
Le fait est qu'en l'exposant au niveau du constructeur (ou de toute autre fonction membre d'une classe):
[*]Tu t'arroges le droit de faire quelque chose qui n'est pas de ta responsabilité en tant que développeur de la classe (à savoir "voler" la responsabilité de la durée de vie à une autre classe que la tienne)
Voler? J'ai du mal à comprendre. Il me semblait qu'on parlait du choix de l'interface d'un composant qui de toute manière considèrera qu'il a seul la responsabilité de la libération.
Citation:
[*]Tu te bases sur la présence du paramètre d'une fonction, qui sera peut être "perdue" au milieu de toutes les autres, pour estimer que cela documente suffisamment le fait que ta classe prend la responsabilité du pointeur, alors que je trouves cela insuffisant et d'une certaine manière dangereux.
Ou il y a un std::move, ou la source de l'unique_ptr est une fonction qui en renvoie un, ce qui ne se fait pas par hasard (tu ne peux pas non plus le "voler" par un simple retour d'une vari
Citation:
[*]La résistance aux exceptions est, dans le cas où tu le passe par valeur en paramètre du constructeur sans doute encore pire que si tu passais le pointeur nu (*)
(*) Ben oui, comme le unique_ptr est déjà créé, il a déjà pris la responsabilité de la durée de vie du pointeur sous-jacent ce qui fait que, si tu as une exception qui survient dans le constructeur, l'objet en question est d'office détruit, sans avoir l'occasion de le récupérer par ailleurs, alors que si tu le passes sous la forme d'un pointeur nu, il te "reste une chance" de pouvoir le faire ;)
J'ai du mal à voir comment tu peux savoir si l'exception intervient avant l'appel (auquel cas tu peux faire quelque chose) ou après que le composant ait déjà pris la responsabilité (auquel cas c'est un bug s'il ne l'a pas libéré). À moins que tu ne découpes plus ton code mais la technique est aussi possible avec un unique_ptr.
Citation:
Claire, au niveau de la fonction qui reçoit le pointeur, mais insuffisante au niveau de la classe, car, à mon sens, il aura trop vite fait de passer inaperçu, surtout si tu t'es amusé à créer un alias de type ;)
À nouveau, un std::move ne va pas passer inaperçu.