Salut,
dans quel cas utilize vous weak_ptr ?
est ce cas que le cas suivant est un bon candidat :
MerciCode:
1
2
3
4
5
6
7
8
9 class Main { Module m; } class Module { weak_ptr<Main> parent; //shared_ptr plutot ? }
Version imprimable
Salut,
dans quel cas utilize vous weak_ptr ?
est ce cas que le cas suivant est un bon candidat :
MerciCode:
1
2
3
4
5
6
7
8
9 class Main { Module m; } class Module { weak_ptr<Main> parent; //shared_ptr plutot ? }
Salut,
Un shared ptr est un pointeur dont la durée de vie est partagée entre différents objets.
Un weak ptr est utilisé lorsqu'on ne veut pas interférer avec la durée de vie du pointeur mais juste pouvoir l'utiliser au besoin (et s'il existe).
Les responsabilités sont différentes : dans un cas, la gestion de la ressource est partagée (shared ptr), dans l'autre non (celui qui a un weak ptr ne gère pas la ressource et peut donc la perdre). Choisir l'un ou l'autre dépend donc de ce critère : partage de sa gestion ou non.
Et il y a les scopped ptr dont la responsabilité est attribuée une fois et n'est pas partagée.
Cf le tuto de Loïc Joly sur les pointeurs intelligents.
Dans ton cas, outre que les cycles peuvent relever d'un problème de design, ça ressemble à une composition entre Main et Module. La durée de vie de m est identique à celle de l'objet Main qui le possède. J'ai l'impression que Module devrait avoir non pas un pointeur mais une référence vers Main, référence initialisée à la construction :
La référence traduit cette dépendance de façon encore plus forte que le pointeur (quelque soit son intelligence).Code:
1
2
3
4
5
6
7
8
9
10 class Main { Module m; } class Module { Module(Main &parent_):parent(parent_){} Main& parent; //shared_ptr plutot ? }
Pour le pbm de design , ce que j'ai voulu éclater une grosse classe en 1 classe et 5 modules .
POur la référence j'y avais pensé mais je shoutais éviter d'avoir à inclure un point .h dans le .h en passant par un pointeur je peux me servir de la forward declaration "class Module.h"
Avec une référence tu peux utiliser une déclaration anticipé dans les headers. C'est comme pour un pointeur.
Pour le pbm de design , ce que j'ai voulu éclater une grosse classe en 1 classe et 5 modules .
POur la référence j'y avais pensé mais je souhaitais éviter d'avoir à inclure un point .h dans le .h. En passant par un pointeur je peux me servir de la forward declaration "class Module;"
Une 'grosse' classe est effectivement une classe avec trop de responsabilités. Les identifier et les réorganiser dans des classes dédiées est une bonne idée. Mais est-ce que les composants ont vraiment besoin de connaître le conteneur ?Citation:
POur la référence j'y avais pensé mais je souhaitais éviter d'avoir à inclure un point .h dans le .h. En passant par un pointeur je peux me servir de la forward declaration "class Module;"
disons que chacun module peut avoir besoin d'une méthode ou attribut d'un autre module
mes modules :
param ( contient le nom , l'id etc du conteneur )
file ( gère les enreg dans un fichier lecture etc)
engine ( effectue tout les calculs )
stat ( calcul et tiens à jour toutes les stats résultant des calculs )
donc sauf cas spécifique comme le module stat qui se fou du module file, à priori tous les modules peuvent avoir à communiquer ensemble
et chaque module est déclaré amie de la classe Conteneur
Généralement, si tout dépend de tout, c'est qu'il y a un problème au niveau du découpage. L'idéal en terme d'une répartition, c'est que si tu traces le graphe de dépendance entre tes modules, ce graphes soit acyclique, sans dépendance circulaire. Comment le faire ? Difficile à dire dans l'abstrait. Parfois en regroupant deux modules, parfois en en créant un nouveau qui supporte des fonctions de bas niveau, parfois en déplaçant quelque chose d'un module à un autre...
Note que je parles bien de module (chose conceptuelles, n'ayant pas vraiment de représentation physique dans le code), et non de classes. Ce n'est pas si gênant d'avoir des dépendances cycliques entre classes, tant que ces classes font partie d'un même module (exemple : Un conteneur et ses itérateurs)
Effectivement. Il y aurait bien la possibilité d'utiliser Boost.Optional pour wrapper ta référence mais je ne sais pas si cela s'articule bien avec la sérialisation. Reste donc le weak_ptr.
boost::serialization ne t'oblige absolument pas à avoir une classe défaut constructible: cf http://www.boost.org/doc/libs/1_43_0...l#constructorsCitation:
le truc c'est que ems classes utilisent boost::serialization est à ce titre doivent comporter un constructeur par défault et de ce fait je doute que je puisse utiliser une reference plutto qu'un pointeur car sur quoi pointerai la référence ?
ok merci, j'étais resté sur boost 1.36