Sauf que ce code déclare une variable Ville de type anonyme. Je pense qu'il manque un typedef pour faire ce que vous vouliez faire.
j'avais en effet plus un typedef en tête. comme présentée ma remarque n'avait pas de sens, à oublier!
Sylvain.
kanze
Jean-Marc Desperrier wrote:
kanze wrote:
Jean-Marc Desperrier wrote:
J'ai l'impression que cela peut cependant donner lieu à un bon exemple d'utilisation des boost::weak_ptr.
Pas du tout. Il faut plus que simplement mettre à null un pointeur.
J'ai l'impression que l'outils peut être utile, même si ce n'est assurément pas la solution complète.
Peut-être dans certains cas, mais c'est loin d'être évident. Comme j'ai dit, j'ai une classe à peu près équivalent, depuis au moins six ou sept ans. Quand je l'ai développé, je croyais aussi qu'il me serait plus généralement utile, mais dans les faits, ce n'a pas été le cas. Il y a toujours eu quelque chose de plus à faire, ce qui supposait une notification. Et une fois le mechanisme de notification en place, il n'y avait plus tellement d'intérêt dans le weak pointer.
La liste globales des villes serait gérée par des boost::shared_ptr, les relations de voisinages par des boost::weak_ptr, une suppression impromptue se régle simplement en n'oubliant pas de tester l'échec de lock() sur les weak_ptr.
Ce qui pose deux problèmes : d'abord, on a introduit une collection globale qui n'y était pas avant, qu'il faut gerer, et deuxièmement, on a une jolie fuite de mémoire, au moins qu'on puisse garantir venir régarder les villes qui n'y sont plus dans chacun des voisin d'avant.
Je me demande si on ne se comprend pas mal. J'avais en tête de partir de ce qu'a proposé Etienne :
struct Ville { int xV; int yV; std::vector <Ville *> voisines; // Cette structure ne fera que // des affectation de pointeurs };
struct Application { std::vector <Ville *> Villes; // C'est cette structure qui fera les "new" };
qui se transforme en :
class Ville { private: std::vector< boost::weak_ptr<Ville> > voisines; public: int xV; int yV; std::vector< boost::shared_ptr<Ville> > getVoisines(); // getVoisines "lock" les voisines dans le vecteur retouné // Au passage, elle nettoye la liste, et en retire les // éléments expiré
C'est un peu lourd, non. Une copie profonde d'un std::vector (ou plusieurs, si le compilateur n'implémente pas NRVO ou RVO). Même en simplifiant :
boost::shared_ptr< Ville > getVoisine( size_t i ) ;
on impose un parcour complet du tableau à chaque accès. Pour détecter un évenement qui est probablement très rare.
Et on introduit un objet de plus, avec le seul but de gérer... mais au fond, de gérer quoi, en fait ? Et comment se prend-on pour supprimer une ville ? L'utilisation de delete n'est certainement pas indiqué.
En fait, il y a deux problèmes à résoudre : il faut s'assurer que le rapport de voisinage soit commutatif, c-à-d que si a est voisin de b, b est voisin d'a, et il faut s'assurer que dans le cas où une ville est supprimée, que tous les rapports de voisinage soient supprimés aussi.
A prioir, le premier impose déjà une gestion supplémentaire -- peut-être au moyen d'une notification. Utiliser la même gestion, ou quelque chose de semblable, dans le cas de suppression d'une ville me semble la solution la plus naturelle. On pourrait même envisager le cas où la ville se déplace -- qu'elle était voisine, mais qu'elle ne l'est plus. Probablement pas très utile dans le rapport de voisinage entre villes, mais dans d'autres rapports, si.
Je n'ai pas attendu Boost pour avoir quelque chose d'équivalent, mais je m'en suis servi en fait assez peu, parce que simplement mettre à null un pointeur, c'est rare que ça suffisait.
Tout seul, certainement, mais il me semble qu'on peut l'utiliser comme brique de base pour construire dessus ce qui marche.
C'est qu'une fois qu'on a en place les notifications, il apporte bien peu. Et qu'en général, il faut les notifications. (Dans le cas de boost::weak_ptr, en plus, il impose boost::shared_ptr, ce qui à sa tour impose une certaine politique en ce qui concerne la durée de vie des objets. Politique qui d'après mes expériences est rarement celle qu'on veut -- depuis que j'utilise le collecteur de Boehm, je crois que je n'ai pas utiliser des pointeurs à comptage de références une seule fois.)
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jean-Marc Desperrier wrote:
kanze wrote:
Jean-Marc Desperrier wrote:
J'ai l'impression que cela peut cependant donner lieu à un bon
exemple d'utilisation des boost::weak_ptr.
Pas du tout. Il faut plus que simplement mettre à null un
pointeur.
J'ai l'impression que l'outils peut être utile, même si ce
n'est assurément pas la solution complète.
Peut-être dans certains cas, mais c'est loin d'être évident.
Comme j'ai dit, j'ai une classe à peu près équivalent, depuis au
moins six ou sept ans. Quand je l'ai développé, je croyais aussi
qu'il me serait plus généralement utile, mais dans les faits, ce
n'a pas été le cas. Il y a toujours eu quelque chose de plus à
faire, ce qui supposait une notification. Et une fois le
mechanisme de notification en place, il n'y avait plus tellement
d'intérêt dans le weak pointer.
La liste globales des villes serait gérée par des
boost::shared_ptr, les relations de voisinages par des
boost::weak_ptr, une suppression impromptue se régle
simplement en n'oubliant pas de tester l'échec de lock()
sur les weak_ptr.
Ce qui pose deux problèmes : d'abord, on a introduit une
collection globale qui n'y était pas avant, qu'il faut
gerer, et deuxièmement, on a une jolie fuite de mémoire, au
moins qu'on puisse garantir venir régarder les villes qui
n'y sont plus dans chacun des voisin d'avant.
Je me demande si on ne se comprend pas mal.
J'avais en tête de partir de ce qu'a proposé Etienne :
struct Ville
{
int xV;
int yV;
std::vector <Ville *> voisines;
// Cette structure ne fera que
// des affectation de pointeurs
};
struct Application
{
std::vector <Ville *> Villes;
// C'est cette structure qui fera les "new"
};
qui se transforme en :
class Ville
{
private:
std::vector< boost::weak_ptr<Ville> > voisines;
public:
int xV;
int yV;
std::vector< boost::shared_ptr<Ville> > getVoisines();
// getVoisines "lock" les voisines dans le vecteur retouné
// Au passage, elle nettoye la liste, et en retire les
// éléments expiré
C'est un peu lourd, non. Une copie profonde d'un std::vector (ou
plusieurs, si le compilateur n'implémente pas NRVO ou RVO). Même
en simplifiant :
boost::shared_ptr< Ville > getVoisine( size_t i ) ;
on impose un parcour complet du tableau à chaque accès. Pour
détecter un évenement qui est probablement très rare.
Et on introduit un objet de plus, avec le seul but de gérer...
mais au fond, de gérer quoi, en fait ? Et comment se prend-on
pour supprimer une ville ? L'utilisation de delete n'est
certainement pas indiqué.
En fait, il y a deux problèmes à résoudre : il faut s'assurer
que le rapport de voisinage soit commutatif, c-à-d que si a est
voisin de b, b est voisin d'a, et il faut s'assurer que dans le
cas où une ville est supprimée, que tous les rapports de
voisinage soient supprimés aussi.
A prioir, le premier impose déjà une gestion supplémentaire --
peut-être au moyen d'une notification. Utiliser la même gestion,
ou quelque chose de semblable, dans le cas de suppression d'une
ville me semble la solution la plus naturelle. On pourrait même
envisager le cas où la ville se déplace -- qu'elle était
voisine, mais qu'elle ne l'est plus. Probablement pas très utile
dans le rapport de voisinage entre villes, mais dans d'autres
rapports, si.
Je n'ai pas attendu Boost pour avoir quelque chose
d'équivalent, mais je m'en suis servi en fait assez peu,
parce que simplement mettre à null un pointeur, c'est rare
que ça suffisait.
Tout seul, certainement, mais il me semble qu'on peut
l'utiliser comme brique de base pour construire dessus ce qui
marche.
C'est qu'une fois qu'on a en place les notifications, il
apporte bien peu. Et qu'en général, il faut les notifications.
(Dans le cas de boost::weak_ptr, en plus, il impose
boost::shared_ptr, ce qui à sa tour impose une certaine
politique en ce qui concerne la durée de vie des objets.
Politique qui d'après mes expériences est rarement celle qu'on
veut -- depuis que j'utilise le collecteur de Boehm, je crois
que je n'ai pas utiliser des pointeurs à comptage de références
une seule fois.)
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
J'ai l'impression que cela peut cependant donner lieu à un bon exemple d'utilisation des boost::weak_ptr.
Pas du tout. Il faut plus que simplement mettre à null un pointeur.
J'ai l'impression que l'outils peut être utile, même si ce n'est assurément pas la solution complète.
Peut-être dans certains cas, mais c'est loin d'être évident. Comme j'ai dit, j'ai une classe à peu près équivalent, depuis au moins six ou sept ans. Quand je l'ai développé, je croyais aussi qu'il me serait plus généralement utile, mais dans les faits, ce n'a pas été le cas. Il y a toujours eu quelque chose de plus à faire, ce qui supposait une notification. Et une fois le mechanisme de notification en place, il n'y avait plus tellement d'intérêt dans le weak pointer.
La liste globales des villes serait gérée par des boost::shared_ptr, les relations de voisinages par des boost::weak_ptr, une suppression impromptue se régle simplement en n'oubliant pas de tester l'échec de lock() sur les weak_ptr.
Ce qui pose deux problèmes : d'abord, on a introduit une collection globale qui n'y était pas avant, qu'il faut gerer, et deuxièmement, on a une jolie fuite de mémoire, au moins qu'on puisse garantir venir régarder les villes qui n'y sont plus dans chacun des voisin d'avant.
Je me demande si on ne se comprend pas mal. J'avais en tête de partir de ce qu'a proposé Etienne :
struct Ville { int xV; int yV; std::vector <Ville *> voisines; // Cette structure ne fera que // des affectation de pointeurs };
struct Application { std::vector <Ville *> Villes; // C'est cette structure qui fera les "new" };
qui se transforme en :
class Ville { private: std::vector< boost::weak_ptr<Ville> > voisines; public: int xV; int yV; std::vector< boost::shared_ptr<Ville> > getVoisines(); // getVoisines "lock" les voisines dans le vecteur retouné // Au passage, elle nettoye la liste, et en retire les // éléments expiré
C'est un peu lourd, non. Une copie profonde d'un std::vector (ou plusieurs, si le compilateur n'implémente pas NRVO ou RVO). Même en simplifiant :
boost::shared_ptr< Ville > getVoisine( size_t i ) ;
on impose un parcour complet du tableau à chaque accès. Pour détecter un évenement qui est probablement très rare.
Et on introduit un objet de plus, avec le seul but de gérer... mais au fond, de gérer quoi, en fait ? Et comment se prend-on pour supprimer une ville ? L'utilisation de delete n'est certainement pas indiqué.
En fait, il y a deux problèmes à résoudre : il faut s'assurer que le rapport de voisinage soit commutatif, c-à-d que si a est voisin de b, b est voisin d'a, et il faut s'assurer que dans le cas où une ville est supprimée, que tous les rapports de voisinage soient supprimés aussi.
A prioir, le premier impose déjà une gestion supplémentaire -- peut-être au moyen d'une notification. Utiliser la même gestion, ou quelque chose de semblable, dans le cas de suppression d'une ville me semble la solution la plus naturelle. On pourrait même envisager le cas où la ville se déplace -- qu'elle était voisine, mais qu'elle ne l'est plus. Probablement pas très utile dans le rapport de voisinage entre villes, mais dans d'autres rapports, si.
Je n'ai pas attendu Boost pour avoir quelque chose d'équivalent, mais je m'en suis servi en fait assez peu, parce que simplement mettre à null un pointeur, c'est rare que ça suffisait.
Tout seul, certainement, mais il me semble qu'on peut l'utiliser comme brique de base pour construire dessus ce qui marche.
C'est qu'une fois qu'on a en place les notifications, il apporte bien peu. Et qu'en général, il faut les notifications. (Dans le cas de boost::weak_ptr, en plus, il impose boost::shared_ptr, ce qui à sa tour impose une certaine politique en ce qui concerne la durée de vie des objets. Politique qui d'après mes expériences est rarement celle qu'on veut -- depuis que j'utilise le collecteur de Boehm, je crois que je n'ai pas utiliser des pointeurs à comptage de références une seule fois.)
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34