Non plus. J'ai tapé le truc à la va-vite car je voulais surtout mettre en évidence l'idiome copy-swap (ce à quoi j'ai magnifiquement échoué parce que j'ai mis un const de trop )...
J'ai corrigé, et je viens d'en profiter pour rajouter un constructeur par défaut.
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
On ne peut pas copier un CSmartPointer défaut-initialisé :
déréférence un pointeur nul!
Code : Sélectionner tout - Visualiser dans une fenêtre à part CSmartPointer<int> p (CSmartPointer ());
re-re-re-corrigé!
Dis, quand on aura fini, on pourra supprimer les postes de corrections ? Ils me dépriment un peu...
(d'un autre côté, je n'ai jamais voulu cacher que c'était codé sur le pouce)
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Oui, j'y avais pensé.
Pourquoi (void)? Pourquoi pas ()?
Code : Sélectionner tout - Visualiser dans une fenêtre à part CSmartPointer(void)
Pourquoi pas d'init-list?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 explicit CSmartPointer(T *p) { this->p = p; this->pr = new int(1); }
- L'habitude de la différence entre () et (void) en C, je préfère mettre systématiquement (void).
- Et donc, ça, ça marche, ça compilera et ça fera exactement ce qu'on veut que ça fasse ? (hormis le contrôle sur les exceptions)
Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 explicit CSmartPointer(T *p) : p(p), pr(new int(1)) { }
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Je ne sais pas pourquoi mais j'avais en tête que ce n'étais pas possible, j'ai du le vérifier pour le croire , mais au final je suppose qu'il est quand même plus clair d'avoir deux noms différents et ça ne coute pas bien cher non... (enfin je suppose que c'est une question de choix personel)...?Envoyé par correctorJe ne suis pas sûr de tout saisir (), quelle serait le code adapté alors... :Envoyé par correctorDans ce cas précis, la gestion d'un bloc catch_try ne coûte pas trop cher en terme de performance?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 CSmartPointer(T *_p) : p(_p) { try{ this->pr = new int(1); } catch(bad_alloc &) { delete p; throw; } }
Juste par curiosité, dans quelle cas ce genre d'exception arrive en général (je n'ai jamais été confronté à ce problème )?
- hp pavillon dv7
- intel(R) Core(TM)2 Duo CPU P8400 @ 2.26GHz 2.27GHz
- nVidia GeForce 9600M GT
- mémoire vive : 3.0Go
Et tant qu'à faire, n'est-il pas préférable d'éviter les exceptions justement :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 CSmartPointer(T *_p) : p(_p), pr(new(nothrow) int(1)) { }
- hp pavillon dv7
- intel(R) Core(TM)2 Duo CPU P8400 @ 2.26GHz 2.27GHz
- nVidia GeForce 9600M GT
- mémoire vive : 3.0Go
Dans un constructeur, pas trop.
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Je retire ce que j'ai dit sur le nothrow () la suite de mon code est basé sur un compteur sencé être alloué correctement donc... voila le code complet de ma classe :Et l'implémentation :
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 template <class T> class CSmartPointer { public: CSmartPointer(T *Pointer = NULL); CSmartPointer(CSmartPointer<T> const &SmartPointer); ~CSmartPointer(); CSmartPointer<T> & operator = (CSmartPointer<T> const &SmartPointer); CSmartPointer<T> & operator = (T *Pointer); bool operator () (); T const * const operator -> () const; T * const operator -> (); T const & operator * () const; T & operator * (); operator T const * const() const; operator T * const(); void Swap(CSmartPointer<T> &SmartPointer); template <class Other> operator CSmartPointer<Other>() const; private: T *m_Pointer; // Pointer on the object int *m_Counter; // Counter on the object pointed };Je ne suis pas encore bien habitué au mot clé explicit mais dans mon projet j'utilise :
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 template <class T> inline CSmartPointer<T>::CSmartPointer(T *Pointer) : m_Pointer(Pointer), m_Counter(NULL) { try{ m_Counter = new int(1); } catch(std::bad_alloc &) { SAFE_DELETE(m_Pointer); throw; } } template <class T> inline CSmartPointer<T>::CSmartPointer(CSmartPointer<T> const &SmartPointer) : m_Pointer(SmartPointer.m_Pointer), m_Counter(SmartPointer.m_Counter) { ++(*m_Counter); } template <class T> inline CSmartPointer<T>::~CSmartPointer() { if( --(*m_Counter) == 0 ) { delete m_Pointer; delete m_Counter; } } template <class T> inline CSmartPointer<T> & CSmartPointer<T>::operator = (CSmartPointer<T> const &SmartPointer) { CSmartPointer<T> CopyTmp(SmartPointer); Swap(CopyTmp); return *this; } template <class T> inline CSmartPointer<T> & CSmartPointer<T>::operator = (T *Pointer) { CSmartPointer<T> CopyTmp(Pointer); Swap(CopyTmp); return *this; } template <class T> inline bool CSmartPointer<T>::operator () () { return(m_Pointer!=NULL); } template <class T> inline T const * const CSmartPointer<T>::operator -> () const { Assert( m_Pointer != NULL ); return m_Pointer; } template <class T> inline T * const CSmartPointer<T>::operator -> () { Assert( m_Pointer != NULL ); return m_Pointer; } template <class T> inline T const & CSmartPointer<T>::operator * () const { Assert( m_Pointer != NULL ); return (*m_Pointer); } template <class T> inline T & CSmartPointer<T>::operator * () { Assert( m_Pointer != NULL ); return (*m_Pointer); } template <class T> inline CSmartPointer<T>::operator T const * const() const { return m_Pointer; } template <class T> inline CSmartPointer<T>::operator T * const() { return m_Pointer; } template <class T> inline void CSmartPointer<T>::Swap(CSmartPointer<T> &SmartPointer) { std::swap(m_Pointer, SmartPointer.m_Pointer); std::swap(m_Counter, SmartPointer.m_Counter); } template <class T> template <class Other> inline CSmartPointer<T>::operator CSmartPointer<Other>() const { Other *Pointer = (Other *)m_Pointer; return CSmartPointer<Other>(Pointer); }Avec AddCamera prenant un smart pointer (de CCamera) en paramètre, dans ce cas il faut bien utiliser le constructeur en tant que conversion implicite non?
Code : Sélectionner tout - Visualiser dans une fenêtre à part SceneManager.AddCamera( new CCamera(*this) );
Enfin si vous avez d'autres conseils ou critiques sur le code je suis preneur encore merci à tous
NOTE : l'opérateur de conversion n'a pas encore était testé(), je ne suis pas sur que ce soit très correct (enfin j'y viendrai...)
- hp pavillon dv7
- intel(R) Core(TM)2 Duo CPU P8400 @ 2.26GHz 2.27GHz
- nVidia GeForce 9600M GT
- mémoire vive : 3.0Go
Je pense que tu peux utiliser le swap aussi sur operator= (T*).
Et aussi, je te pose la question avant corrector: Constructeur implicite, c'est voulu ?
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
En effet ça semble fonctionner, c'est modifé merciEnvoyé par MédinocEn prévision a cette question qui m'a était posé 3fois j'ai laissé ce message :Et aussi, je te pose la question avant corrector: Constructeur implicite, c'est voulu ?Pourquoi cette question revient-elle? Il y a des risques (dans mon cas)?Envoyé par babar63
- hp pavillon dv7
- intel(R) Core(TM)2 Duo CPU P8400 @ 2.26GHz 2.27GHz
- nVidia GeForce 9600M GT
- mémoire vive : 3.0Go
OK. En effet, là, le constructeur implicite est requis, je pense.
Et pour les risques, je ne sais pas trop à part des risques de confusion. J'ai surtout posé la question par mimétisme, parce que corrector la posait...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Dans la classe elle-même, tu peux écrire CSmartPointer à la place de CSmartPointer<T>.
Pourquoi faire un foncteur?
Pourquoi la distinction const/non const?
(Soit rigoureux dans ton explication.)Pourquoi faire une fonction séparée? Tu ne l'appelles qu'une seule fois.
Ces parenthèses sont redondantes.
Ces parenthèses sont redondantes.
Ces parenthèses sont redondantes.
Pourquoi SAFE_DELETE?
En effet, ce n'est pas forcément approprié. Mais ça peut aussi l'être, dépendant des circonstances. Enfin, je crois. Mais en y réfléchissant plus, je ne vois plus trop où, les exemples que j'avaient en tête s'écroulent dès que j'y pense plus d'une seconde...Pourquoi la distinction const/non const?
Pour bien faire, il faudrait peut-être deux versions de la classe: Une qui fait des contrôles comme ça, une autre où la constance de l'objet est complètement dissociée de celle du pointeur intelligent...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
D'après la FAQ c'est un prédicat si j'ai bien compris, je l'utilise simplement pour tester si mon objet pointé est valide(NULL) ou non.Envoyé par correctorN'est-il pas correct d'utiliser un maximum de const lorsqu'on le peut? Voila un exemple de mon projet qui utilise la fonctionEnvoyé par corrector
Code : Sélectionner tout - Visualiser dans une fenêtre à part T const * const operator -> () const;Je suppose que je n'ai pas besoin de montrer d'exemple pour le même opérateur sans tous ces consts , ce n'est donc pas correct? pourquoi?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 //fonction membre de CSeneManager : std::vector<ILightPtr> const & GetLights() const { return m_Scene->Lights; // Un vecteur de ILightPtr membre de la class }Je fais de mon mieux mais je suis en train d'apprendre donc je ne peux pas toujours expliquer comme il le faudrait, sans doute je l'ai vu quelques part, ça m'a parut intelligent, j'ai gardé l'idée et je la ressort de temps en temps .Envoyé par correctorJustement je l'appelais dans mon opérateur :Envoyé par correctorQue j'ai modifié à la suite de la remarque de médinoc, mais j'ai oublié de supprimer la fonction après...(je le fais de suite)
Code : Sélectionner tout - Visualiser dans une fenêtre à part CSmartPointer<T> & operator = (T *Pointer);Je préfère parfois mettre un peu plus de parenthèse, dans la limite du raisonnable je trouve le code plus clair... Est-ce un mauvais réflexe?Envoyé par correctorEuh........ Pour le coup j'avoue que je ne vois plus donc sans doute une mauvaise raison . En revanche le deuxième :Envoyé par correctorest correct non? Je l'utilise pour supprimer m_Pointer si il est NULL et le réinitialiser à NULL
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 catch(std::bad_alloc &) { SAFE_DELETE(m_Pointer); throw; }
- hp pavillon dv7
- intel(R) Core(TM)2 Duo CPU P8400 @ 2.26GHz 2.27GHz
- nVidia GeForce 9600M GT
- mémoire vive : 3.0Go
Le problème, c'est que ce code suppose que dès que le pointeur est constant, les données pointées le sont aussi.N'est-il pas correct d'utiliser un maximum de const lorsqu'on le peut? Voila un exemple de mon projet qui utilise la fonction
<snip>
Je suppose que je n'ai pas besoin de montrer d'exemple pour le même opérateur sans tous ces consts , ce n'est donc pas correct? pourquoi?
Si tu veux un smart pointer vers des données constantes, tu peux en faire un qui retourne toujours un T* et juste faire un CSmartPointer< const int > par exemple...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager