Bonjour à tous !
Je viens vers vous, car j'ai un souci sur une classe singleton que je souhaite créer. Je sais que le singleton crée toujours un débat, mais mon poste ne concerne pas ce débat, mais plutôt un souhait de ma part de l'utiliser pour mon amusement à moi et surtout pour connaître sa création dans un contexte du petit projet que je me construis pour améliorer mes connaissances globales.
Je souhaite aussi dire que je ne suis pas expert en création du post sur les forums (pas pour l'instant) donc si vous avez des conseils, que vous trouver que j'ai mal créé mon poste ou mes questions, je suis preneur de tous vos conseils. (je suis débutant, merci de votre gentillesse.)
J'attaque le sujet.
Le contexte de ma classe est assez simple, c'est un container que j'utilise comme un cache qui me permet de stocker et d'utiliser les valeurs voulues en les identifiants par des clés bien précises (ma classe utilise la lib boost)
Je vous copie ici ma classe de base qui fonctionne pour avoir une idée.
Par la suite j'ai voulu utilise le pattern singleton, donc j'ai recherché et testé différentes idées (je pense même etre parti en hors sujet à certains moments ou avoir fait trop compliquer pour quelque chose de simple). Ce qui me donnait ceci
Code : 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 #include <boost/multi_index_container.hpp> #include <boost/multi_index/sequenced_index.hpp> #include <boost/multi_index/hashed_index.hpp> #include <boost/multi_index/key.hpp> template<typename Tkey, typename Tval> class CacheWeb{ private: using value_type = std::pair<Tkey, Tval>; unsigned int capacity; boost::multi_index_container< value_type, boost::multi_index::indexed_by< boost::multi_index::sequenced<>, boost::multi_index::hashed_unique<boost::multi_index::key<&value_type::first>> > > container; CacheWeb(const CacheWeb&) = delete; CacheWeb& operator=(const CacheWeb&) = delete; int capacityOut(){ if( capacity == 0 || container.size() < capacity ) { return 0; } int cnt = 0; while(container.size() > capacity) { container.pop_back(); ++cnt; } return cnt; }; public: CacheWeb(int icapacity) : capacity(icapacity){}; virtual ~CacheWeb() = default; int size(){ return container.size(); }; bool empty(){ return container.empty(); }; void clear(){ container.clear(); }; bool contains(const Tkey& key){ const auto& lookup = container.template get<1>(); return lookup.find(key) != container.template get<1>().end(); }; void remove(const Tkey& key){ container.erase(key); }; void put(const Tkey& key, const Tval& val){ auto& lookup = container.template get<1>(); auto it = lookup.find(key); if( it != lookup.end() ) { lookup.modify(it,[&](value_type& x){ x.second = val; }); } else{ it=lookup.emplace(key, val).first; } container.relocate(container.begin(),container.template project<0>(it)); capacityOut(); }; std::list<std::pair<Tkey, Tval>>getItems(){ return {container.begin(), container.end()}; }; const Tval& get(const Tkey& key){ const auto& lookup = container.template get<1>(); const auto it = lookup.find(key); if( it == lookup.end() ) { throw std::invalid_argument("Key does not exist"); } return it->second; } }; #include <iostream> int main() { CacheWeb<int,int> c(10); for(int i=0;i<11;++i)c.put(i,i); for(const auto& x:c.getItems()){ std::cout<<"("<<x.first<<","<<x.second<<")"; } std::cout<<"\n"; for(int i=1;i<11;++i){ std::cout<<i<<"->"<<c.get(i)<<" "; } std::cout<<"\n"; }
Le souci c'est qu'en testant, j'ai obtenu une erreur celle-ci: a nonstatic member reference must be relative to a specific object
Code : 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 #include <boost/multi_index_container.hpp> #include <boost/multi_index/sequenced_index.hpp> #include <boost/multi_index/hashed_index.hpp> #include <boost/multi_index/identity.hpp> #include <boost/multi_index/member.hpp> #include <boost/config.hpp> #include <iostream> #include <stdexcept> #include <list> template<typename KEY_T, typename VAL_T> class MultiContainer{ private: using value_type = std::pair<KEY_T, VAL_T>; static MultiContainer<KEY_T, VAL_T>* _singletonCacheServer; unsigned int _capacity; boost::multi_index_container<value_type,boost::multi_index::indexed_by<boost::multi_index::sequenced<>, boost::multi_index::hashed_unique<boost::multi_index::member<value_type,KEY_T,&value_type::first>>>> _container; MultiContainer(const MultiContainer&) = delete; MultiContainer& operator=(const MultiContainer&) = delete; int capacityOut(){ if( _capacity == 0 || _container.size() < _capacity ) { return 0; } int cnt = 0; while(_container.size() > _capacity) { _container.pop_back(); ++cnt; } return cnt; }; public: MultiContainer(int icapacity) : _capacity(icapacity){}; virtual ~MultiContainer() = default; MultiContainer(); static MultiContainer<KEY_T, VAL_T>& getInstance() { if (!_singletonCacheServer) { _singletonCacheServer = new MultiContainer; }else{ delete _singletonCacheServer; _singletonCacheServer = nullptr; } return _singletonCacheServer; } int size(){ return _container.size(); }; bool empty(){ return _container.empty(); }; void clear(){ _container.clear(); }; bool contains(const KEY_T& key){ const auto& lookup = _container.template get<1>(); return lookup.find(key) != _container.template get<1>().end(); }; void remove_key(const KEY_T& key){ auto& lookup = _container.template get<1>(); auto it = lookup.find(key); if(it != lookup.end()){ lookup.erase(it); } } void put(const KEY_T& key, const VAL_T& val){ auto& lookup = _container.template get<1>(); auto it = lookup.find(key); if( it != lookup.end() ) { lookup.modify(it,[&](value_type& x){ x.second = val; }); } else{ it=lookup.emplace(key, val).first; } _container.relocate(_container.begin(),_container.template project<0>(it)); capacityOut(); }; std::list<std::pair<KEY_T, VAL_T>>getItems(){ return {_container.begin(), _container.end()}; }; const VAL_T& get(const KEY_T& key){ const auto& lookup = _container.template get<1>(); const auto it = lookup.find(key); if( it == lookup.end() ) { throw std::invalid_argument("Key does not exist"); } return it->second; } }; int main() { MultiContainer<std::string, std::string>* a1 = MultiContainer<std::string, std::string>::getInstance(); //auto cache = MultiContainer<std::string, std::string>::getInstance(); }
À cause de cette erreur je me suis dit que j'ai mal construit mon singleton car s'il me demande un objet cela voudrait dire que le principe de singleton ne fonctionne pas.
Quelles sont les erreurs que j'ai pu faire ? pour pouvoir enfin réussir à faire fonctionner ma classe
Voilà j'ai peur d'avoir pas assez expliqué, donc merci si vous me lisez et je ferais le nécessaire pour corriger, améliorer mon poste. Bonne Année à vous
ps: j'aurais une deuxième question par la suite "dans quel fichier utilisé le singleton" mais cela viendra après
Partager