Salut!
J'ai codé 3 classes pour gérer des pointeurs intelligent, la 1ère est équivalente à std::shared_ptr, la seconde à std::unique_ptr et la troisième à std::weak_ptr à part qu'elle est aussi utilisable pour les pointeurs uniques.
J'en ai profité pour rajouté un constructeur qui prend aussi un pointeur, et pas qu'un new.
Ce qui donne quelque chose comme ceci :
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 odfaeg::UniquePointer<int> ptr = odfaeg::make_unique<int>(5); odfaeg::WeakPointer tmpptr = ptr;
Bref, la classe WeakPtr sert juste pour l'utilisation temporaire des pointeurs intelligents, donc, l'objet n'est que temporairement propriétaire du pointeur, si le vrai propriétaire est détruit alors le pointeur temporaire devient invalide et une exception est lancée au cas ou on essayerais de l'utiliser.
Tandis que les 2 autres classes servent dans les contextes suivants :
UniquePointer sert à donner la propriété unique du pointeur à un objet et est utilisé dans la plupart des cas.
SharedPointer sert à donner la propriété à plusieurs objets, ce cas, je ne l'utilise que si plusieurs thread utilisent la même ressources et si je ne veux bloquer le programme et attendre que tout les threads aient fini d'utiliser la ressource avant de la libérer.
En plus de cela, UniquePointer et SharedPointer peuvent devenir propriétaire d'un pointeur nu, ils prennent alors la responsabilité de le détruire si par exemple le pointeur doit être alloué autrement que via make_unique ou bien make_shared.
Pour les pointeurs statiques, ceux-ci sont détruit tout à la fin de l'exécution du programme, car, ces classes contiennent un singleton pour tout les pointeurs de même type qui se charge de libérer tout ce qui doit être libéré à la fin du programme. (C'est le deleter et il me sert aussi bien pour les ressources interne c'est à dire celle allouer sur le tas que pour les ressources externes c'est à dire, celles chargée à partir d'une fonction de chargement.)
Bref ceci fonctionne bien (j'ai testé) même dans un contexte multi-thread.
Maintenant, ce que je veux, c'est faire la même chose avec les containers de la STL.
Pour simplifier la syntaxe j'ai fais un bon nombre de usings :
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 template <class H> using SharedVectorPointer = SmartContainerPointer<std::vector<SharedPointer<H>>>; template <class H, class T> using SharedMapPointerK = SmartContainerPointer<std::map<SharedPointer<H>, T>>; template <class H, class T> using SharedMapPointerV = SmartContainerPointer<std::map<H, SharedPointer<T>>>; template <class H, class T> using SharedMapPointer = SmartContainerPointer<std::map<SharedPointer<H>, SharedPointer<T>>>; template <class H> using UniqueVectorPointer = SmartContainerPointer<std::vector<UniquePointer<H>>>; template <class H, class T> using UniqueMapPointerK = SmartContainerPointer<std::map<UniquePointer<H>, T>>; template <class H, class T> using UniqueMapPointerV = SmartContainerPointer<std::map<H, UniquePointer<T>>>; template <class H, class T> using UniqueMapPointer = SmartContainerPointer<std::map<UniquePointer<H>, UniquePointer<T>>>; template <class H> using WeakVectorPointer = SmartContainerPointer<std::vector<WeakPointer<H>>>; template <class H, class T> using WeakMapPointerK = SmartContainerPointer<std::map<WeakPointer<H>, T>>; template <class H, class T> using WeakMapPointerV = SmartContainerPointer<std::map<H, WeakPointer<T>>>; template <class H, class T> using WeakMapPointer = SmartContainerPointer<std::map<WeakPointer<H>, WeakPointer<T>>>;
Ce que je voudrais c'est pouvoir convertir un std::vector de SharedPointer ou bien de UniquePointer en un vector de WeakPointer pour une utilisation temporaire du vecteur de pointeurs.
J'ai alors essayé de faire ceci :
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 template <template <typename> class C, class H> class SmartContainerPointer<C<WeakPointer<H>>> : public C<WeakPointer<H>> { public : SmartContainerPointer<C<WeakPointer<H>>> (const SmartContainerPointer<C<SharedPointer<H>>>& scp) { typename SmartContainerPointer<C<SharedPointer<H>>>::iterator it; for (it = scp.begin(); it != scp.end(); it++) { push_back(WeakPointer<H>(*it)); } } SmartContainerPointer<C<WeakPointer<H>>> (const SmartContainerPointer<C<UniquePointer<H>>>& scp) { typename SmartContainerPointer<C<UniquePointer<H>>>::iterator it; for (it = scp.begin(); it != scp.end(); it++) { push_back(WeakPointer<H>(*it)); } } SmartContainerPointer<C<WeakPointer<H>>>& operator=(const SmartContainerPointer<C<SharedPointer<H>>>& scp) { typename SmartContainerPointer<C<SharedPointer<H>>>::iterator it; for (it = scp.begin(); it != scp.end(); it++) { push_back(WeakPointer<H>(*it)); } return *this; } SmartContainerPointer<C<WeakPointer<H>>>& operator=(const SmartContainerPointer<C<UniquePointer<H>>>& scp) { typename SmartContainerPointer<C<UniquePointer<H>>>::iterator it; for (it = scp.begin(); it != scp.end(); it++) { push_back(WeakPointer<H>(*it)); } return *this; } };
Mais, cela ne fonctionne pas, ce code-ci
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 odfaeg::SharedVectorPointer<int> svp; odfaeg::WeakVectorPointer<int> wvp = svp;
Me renvoie à cette erreur là.
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp|5|error: conversion from odfaeg::SharedVectorPointer<int> {aka odfaeg::SmartContainerPointer<std::vector<odfaeg::SharedPointer<int>, std::allocator<odfaeg::SharedPointer<int> > > >} to non-scalar type odfaeg::WeakVectorPointer<int> {aka odfaeg::SmartContainerPointer<std::vector<odfaeg::WeakPointer<int>, std::allocator<odfaeg::WeakPointer<int> > > >} requested|
N'y a t'il pas moyen de redéfinir l'opérateur= pour convertir un contenaire de type X en un contenaire de type Y ?
J'ai pas envie de recoder la STL pour devoir faire cela. (Malgré mon côté pervers de réinventer la roue pour apprendre.)
Sinon, obligation de passer par un fonction libre pour effectuer la conversion.
l'opérateur = de std::vector affecte t'il le std::vector ou bien chaque élément du vecteur séparément ?
Si c'est la 1ère réponse y a t'il moyen de changer le code de cette classe et de recompiler la STL ?
Merci d'avance pour vos réponse.
Partager