j'ai un petit probleme avec la gestion d'une mémoire allouée
dynamiquement dans une fonction
vect &
vect::operator+(const vect &v) const
{
vect *p = new vect;
for(unsigned int i=0; i<x.size(); i ++)
{
*(p->x[i]) = (*x[i] + *(v.x[i]));
}
return *p;
}
imaginons que 'vect' soit un objet comprenant un vector 'x' qui lui
même contient un ensemble de pointeurs sur des objets dont la nature
nous importe peut (nous savons qu'ils ont un opérateur '+' défini)
je veux définir l'opérateur '+' pour mon objet 'vect', qui devra
additionner tous les objets pointés par son vector 'x' avec ceux
pointés par un autre vect.
pour celà j'alloue dynamiquement un espace mémoire de type 'vect', puis
je boucle sur le tableau, en espérant que cette ligne a l'intérieur de
la boucle soit correcte...
puis je retourne une référence sur mon objet dynamique avec 'return
*p;'
maintenant imaginons que j'utilise cet opérateur dans une autre
fonction :
{
vect a,b,c;
a = b + c;
}
comment a la sortie de la fonction libérer la mémoire alouée ??
j'ai un petit probleme avec la gestion d'une mémoire allouée dynamiquement dans une fonction
vect & vect::operator+(const vect &v) const { vect *p = new vect; for(unsigned int i=0; i<x.size(); i ++) { *(p->x[i]) = (*x[i] + *(v.x[i])); } return *p; }
imaginons que 'vect' soit un objet comprenant un vector 'x' qui lui même contient un ensemble de pointeurs sur des objets dont la nature nous importe peut (nous savons qu'ils ont un opérateur '+' défini)
je veux définir l'opérateur '+' pour mon objet 'vect', qui devra additionner tous les objets pointés par son vector 'x' avec ceux pointés par un autre vect.
pour celà j'alloue dynamiquement un espace mémoire de type 'vect', puis je boucle sur le tableau, en espérant que cette ligne a l'intérieur de la boucle soit correcte...
Tout depend de ce que fait :
new vect
Mais je doute que p->x.size() soit non nul. Utilise
*(p->at(i)) = (*x[i] + *(v.x[i]));
puis je retourne une référence sur mon objet dynamique avec 'return *p;'
Pourquoi ne pas retourner le pointeur ?
maintenant imaginons que j'utilise cet opérateur dans une autre fonction :
{
vect a,b,c;
a = b + c;
}
comment a la sortie de la fonction libérer la mémoire alouée ??
delete & a
mais ce n'est pas une bonne idée. Voir std::auto_ptr<>. Ou mieux utiliser le principe RAI et faire de x un pointeur sur vector. -- Franck Branjonneau
Nicolas Aunai <nicolas.aunai@free.fr> écrivait:
j'ai un petit probleme avec la gestion d'une mémoire allouée
dynamiquement dans une fonction
vect &
vect::operator+(const vect &v) const
{
vect *p = new vect;
for(unsigned int i=0; i<x.size(); i ++)
{
*(p->x[i]) = (*x[i] + *(v.x[i]));
}
return *p;
}
imaginons que 'vect' soit un objet comprenant un vector 'x' qui lui
même contient un ensemble de pointeurs sur des objets dont la nature
nous importe peut (nous savons qu'ils ont un opérateur '+' défini)
je veux définir l'opérateur '+' pour mon objet 'vect', qui devra
additionner tous les objets pointés par son vector 'x' avec ceux
pointés par un autre vect.
pour celà j'alloue dynamiquement un espace mémoire de type 'vect',
puis je boucle sur le tableau, en espérant que cette ligne a
l'intérieur de la boucle soit correcte...
Tout depend de ce que fait :
new vect
Mais je doute que p->x.size() soit non nul. Utilise
*(p->at(i)) = (*x[i] + *(v.x[i]));
puis je retourne une référence sur mon objet dynamique avec 'return
*p;'
Pourquoi ne pas retourner le pointeur ?
maintenant imaginons que j'utilise cet opérateur dans une autre
fonction :
{
vect a,b,c;
a = b + c;
}
comment a la sortie de la fonction libérer la mémoire alouée ??
delete & a
mais ce n'est pas une bonne idée. Voir std::auto_ptr<>. Ou mieux
utiliser le principe RAI et faire de x un pointeur sur vector.
--
Franck Branjonneau <fasbjx@free.fr>
j'ai un petit probleme avec la gestion d'une mémoire allouée dynamiquement dans une fonction
vect & vect::operator+(const vect &v) const { vect *p = new vect; for(unsigned int i=0; i<x.size(); i ++) { *(p->x[i]) = (*x[i] + *(v.x[i])); } return *p; }
imaginons que 'vect' soit un objet comprenant un vector 'x' qui lui même contient un ensemble de pointeurs sur des objets dont la nature nous importe peut (nous savons qu'ils ont un opérateur '+' défini)
je veux définir l'opérateur '+' pour mon objet 'vect', qui devra additionner tous les objets pointés par son vector 'x' avec ceux pointés par un autre vect.
pour celà j'alloue dynamiquement un espace mémoire de type 'vect', puis je boucle sur le tableau, en espérant que cette ligne a l'intérieur de la boucle soit correcte...
Tout depend de ce que fait :
new vect
Mais je doute que p->x.size() soit non nul. Utilise
*(p->at(i)) = (*x[i] + *(v.x[i]));
puis je retourne une référence sur mon objet dynamique avec 'return *p;'
Pourquoi ne pas retourner le pointeur ?
maintenant imaginons que j'utilise cet opérateur dans une autre fonction :
{
vect a,b,c;
a = b + c;
}
comment a la sortie de la fonction libérer la mémoire alouée ??
delete & a
mais ce n'est pas une bonne idée. Voir std::auto_ptr<>. Ou mieux utiliser le principe RAI et faire de x un pointeur sur vector. -- Franck Branjonneau
Nicolas Aunai
Il se trouve que Franck Branjonneau a formulé :
Tout depend de ce que fait :
new vect
j'ai rien touché à 'new'...
Mais je doute que p->x.size() soit non nul. Utilise
*(p->at(i)) = (*x[i] + *(v.x[i]));
ok mon vector sera vide... mais pourquoi utiliser at() ? si mon vector est vide je devrai plutôt utiliser :
p->x->push_back((*x[i] + *(v.x[i])));
non ?
puis je retourne une référence sur mon objet dynamique avec 'return *p;'
Pourquoi ne pas retourner le pointeur ?
pour savoir comment on fait avec les références, j'ai encore un peu de mal avec elles...
comment a la sortie de la fonction libérer la mémoire alouée ??
delete & a
ah bon... comprendrai jamais rien a new/delete...
mais ce n'est pas une bonne idée. Voir std::auto_ptr<>.
connait pas... je regarde
Ou mieux utiliser le principe RAI et faire de x un pointeur sur vector.
j'ai un petit probleme avec la gestion d'une mémoire allouée dynamiquement dans une fonction
vect & vect::operator+(const vect &v) const
En général, on déclare l'opérateur + en dehors de la classe. Ceci pour des raisons de symétrie (sinon, le premier terme doit être un vect, et le deuxième un truc castable en vect, ce qui rompt la symétrie de l'addition) (et on défini operator+ à partir de operator+=).
Ensuite, l'opérateur devrait retourner un objet, et non pas une référence ou un pointeur. Ca peut poser des problèmes de performance, puisque du coup l'objet va être copié, mais ce problème peut être réduit :
- Certains compilateur implémentent la RVO (return value optimisation), qui leur permet d'éviter une copie dans ce genre de cas. - Il est possible de retourner non pas un vecteur mais un objet qui se souvient de l'opération effectuée, et ne va réellement additionner que quand on va accèder au contenu, tout en faisant cette gymnastique à la compilation (voir par exemple blitz::tiny_vector sur www.oonumerics.org, se munir d'une aspirine) - Certains travaillent à founir au C++ une sémantique de déplacement en plus de la sémantique de copie omniprésente actuellement. Si ton programme peut attendre quelques années... ;) - Dans certains cas, une fonction void add (vect const &A, vect const &B, vect &Result) peut aider, mais l'écriture n'est vraiment pas belle.
-- Loïc
Nicolas Aunai wrote:
salut,
j'ai un petit probleme avec la gestion d'une mémoire allouée
dynamiquement dans une fonction
vect &
vect::operator+(const vect &v) const
En général, on déclare l'opérateur + en dehors de la classe. Ceci pour
des raisons de symétrie (sinon, le premier terme doit être un vect, et
le deuxième un truc castable en vect, ce qui rompt la symétrie de
l'addition) (et on défini operator+ à partir de operator+=).
Ensuite, l'opérateur devrait retourner un objet, et non pas une
référence ou un pointeur. Ca peut poser des problèmes de performance,
puisque du coup l'objet va être copié, mais ce problème peut être réduit :
- Certains compilateur implémentent la RVO (return value optimisation),
qui leur permet d'éviter une copie dans ce genre de cas.
- Il est possible de retourner non pas un vecteur mais un objet qui se
souvient de l'opération effectuée, et ne va réellement additionner que
quand on va accèder au contenu, tout en faisant cette gymnastique à la
compilation (voir par exemple blitz::tiny_vector sur www.oonumerics.org,
se munir d'une aspirine)
- Certains travaillent à founir au C++ une sémantique de déplacement en
plus de la sémantique de copie omniprésente actuellement. Si ton
programme peut attendre quelques années... ;)
- Dans certains cas, une fonction void add (vect const &A, vect const
&B, vect &Result) peut aider, mais l'écriture n'est vraiment pas belle.
j'ai un petit probleme avec la gestion d'une mémoire allouée dynamiquement dans une fonction
vect & vect::operator+(const vect &v) const
En général, on déclare l'opérateur + en dehors de la classe. Ceci pour des raisons de symétrie (sinon, le premier terme doit être un vect, et le deuxième un truc castable en vect, ce qui rompt la symétrie de l'addition) (et on défini operator+ à partir de operator+=).
Ensuite, l'opérateur devrait retourner un objet, et non pas une référence ou un pointeur. Ca peut poser des problèmes de performance, puisque du coup l'objet va être copié, mais ce problème peut être réduit :
- Certains compilateur implémentent la RVO (return value optimisation), qui leur permet d'éviter une copie dans ce genre de cas. - Il est possible de retourner non pas un vecteur mais un objet qui se souvient de l'opération effectuée, et ne va réellement additionner que quand on va accèder au contenu, tout en faisant cette gymnastique à la compilation (voir par exemple blitz::tiny_vector sur www.oonumerics.org, se munir d'une aspirine) - Certains travaillent à founir au C++ une sémantique de déplacement en plus de la sémantique de copie omniprésente actuellement. Si ton programme peut attendre quelques années... ;) - Dans certains cas, une fonction void add (vect const &A, vect const &B, vect &Result) peut aider, mais l'écriture n'est vraiment pas belle.
-- Loïc
Nicolas Aunai
Loïc Joly a exprimé avec précision :
vect & vect::operator+(const vect &v) const
En général, on déclare l'opérateur + en dehors de la classe. Ceci pour des raisons de symétrie (sinon, le premier terme doit être un vect, et le deuxième un truc castable en vect, ce qui rompt la symétrie de l'addition) (et on défini operator+ à partir de operator+=).
ah bon, tiens donc....
Ensuite, l'opérateur devrait retourner un objet, et non pas une référence ou un pointeur. Ca peut poser des problèmes de performance, puisque du coup l'objet va être copié,
en effet !
mais ce problème peut être réduit :
- Certains compilateur implémentent la RVO (return value optimisation), qui leur permet d'éviter une copie dans ce genre de cas.
mouais... j'aime pas trop qu'un code dépende d'un compilo
- Il est possible de retourner non pas un vecteur mais un objet qui se souvient de l'opération effectuée, et ne va réellement additionner que quand on va accèder au contenu, tout en faisant cette gymnastique à la compilation (voir par exemple blitz::tiny_vector sur www.oonumerics.org, se munir d'une aspirine)
je sens le "trop compliqué" d'avance... :-(
- Certains travaillent à founir au C++ une sémantique de déplacement en plus de la sémantique de copie omniprésente actuellement. Si ton programme peut attendre quelques années... ;)
nan :-)
- Dans certains cas, une fonction void add (vect const &A, vect const &B, vect &Result) peut aider, mais l'écriture n'est vraiment pas belle.
pas belle pas belle... c'est surtout qu'on perd l'intéret du C++ dans l'affaire : les opérateurs surchargés... et dans ces conditions je préfère retourner d'où je viens : le C :-)
décidément le C++ c'est pas mal, mais y'a trop de trucs ;-)
En général, on déclare l'opérateur + en dehors de la classe. Ceci pour des
raisons de symétrie (sinon, le premier terme doit être un vect, et le
deuxième un truc castable en vect, ce qui rompt la symétrie de l'addition)
(et on défini operator+ à partir de operator+=).
ah bon, tiens donc....
Ensuite, l'opérateur devrait retourner un objet, et non pas une référence ou
un pointeur. Ca peut poser des problèmes de performance, puisque du coup
l'objet va être copié,
en effet !
mais ce problème peut être réduit :
- Certains compilateur implémentent la RVO (return value optimisation), qui
leur permet d'éviter une copie dans ce genre de cas.
mouais... j'aime pas trop qu'un code dépende d'un compilo
- Il est possible de retourner non pas un vecteur mais un objet qui se
souvient de l'opération effectuée, et ne va réellement additionner que quand
on va accèder au contenu, tout en faisant cette gymnastique à la compilation
(voir par exemple blitz::tiny_vector sur www.oonumerics.org, se munir d'une
aspirine)
je sens le "trop compliqué" d'avance... :-(
- Certains travaillent à founir au C++ une sémantique de déplacement en plus
de la sémantique de copie omniprésente actuellement. Si ton programme peut
attendre quelques années... ;)
nan :-)
- Dans certains cas, une fonction void add (vect const &A, vect const &B,
vect &Result) peut aider, mais l'écriture n'est vraiment pas belle.
pas belle pas belle... c'est surtout qu'on perd l'intéret du C++ dans
l'affaire : les opérateurs surchargés... et dans ces conditions je
préfère retourner d'où je viens : le C :-)
décidément le C++ c'est pas mal, mais y'a trop de trucs ;-)
En général, on déclare l'opérateur + en dehors de la classe. Ceci pour des raisons de symétrie (sinon, le premier terme doit être un vect, et le deuxième un truc castable en vect, ce qui rompt la symétrie de l'addition) (et on défini operator+ à partir de operator+=).
ah bon, tiens donc....
Ensuite, l'opérateur devrait retourner un objet, et non pas une référence ou un pointeur. Ca peut poser des problèmes de performance, puisque du coup l'objet va être copié,
en effet !
mais ce problème peut être réduit :
- Certains compilateur implémentent la RVO (return value optimisation), qui leur permet d'éviter une copie dans ce genre de cas.
mouais... j'aime pas trop qu'un code dépende d'un compilo
- Il est possible de retourner non pas un vecteur mais un objet qui se souvient de l'opération effectuée, et ne va réellement additionner que quand on va accèder au contenu, tout en faisant cette gymnastique à la compilation (voir par exemple blitz::tiny_vector sur www.oonumerics.org, se munir d'une aspirine)
je sens le "trop compliqué" d'avance... :-(
- Certains travaillent à founir au C++ une sémantique de déplacement en plus de la sémantique de copie omniprésente actuellement. Si ton programme peut attendre quelques années... ;)
nan :-)
- Dans certains cas, une fonction void add (vect const &A, vect const &B, vect &Result) peut aider, mais l'écriture n'est vraiment pas belle.
pas belle pas belle... c'est surtout qu'on perd l'intéret du C++ dans l'affaire : les opérateurs surchargés... et dans ces conditions je préfère retourner d'où je viens : le C :-)
décidément le C++ c'est pas mal, mais y'a trop de trucs ;-)
En général, on déclare l'opérateur + en dehors de la classe. Ceci pour des raisons de symétrie (sinon, le premier terme doit être un vect, et le deuxième un truc castable en vect, ce qui rompt la symétrie de l'addition) (et on défini operator+ à partir de operator+=).
ah bon, tiens donc....
Ensuite, l'opérateur devrait retourner un objet, et non pas une référence ou un pointeur. Ca peut poser des problèmes de performance, puisque du coup l'objet va être copié,
en effet !
Mieux vaut un programme lent et correct qu'un programme rapide et faux.
mais ce problème peut être réduit :
- Certains compilateur implémentent la RVO (return value optimisation), qui leur permet d'éviter une copie dans ce genre de cas.
mouais... j'aime pas trop qu'un code dépende d'un compilo
Le code n'en dépend pas, seule sa rapidité (à condition que tu aies joué le jeu en définissant un constructeur de copie qui copie vraiment(*)). Comme tout ce qui est de la rapidité d'ailleur. Tu n'est assuré de rien en passant d'un compilo à l'autre en matière de performances.
- Il est possible de retourner non pas un vecteur mais un objet qui se souvient de l'opération effectuée, et ne va réellement additionner que quand on va accèder au contenu, tout en faisant cette gymnastique à la compilation (voir par exemple blitz::tiny_vector sur www.oonumerics.org, se munir d'une aspirine)
je sens le "trop compliqué" d'avance... :-(
Ca dépend d'où tu te place. Point de vue utilisateur, ça s'utilise de façon transparente, point de vue implémenteur, c'est effectivement un peu coton.
- Certains travaillent à founir au C++ une sémantique de déplacement en plus de la sémantique de copie omniprésente actuellement. Si ton programme peut attendre quelques années... ;)
nan :-)
Bon, dommage...
- Dans certains cas, une fonction void add (vect const &A, vect const &B, vect &Result) peut aider, mais l'écriture n'est vraiment pas belle.
pas belle pas belle... c'est surtout qu'on perd l'intéret du C++ dans l'affaire : les opérateurs surchargés... et dans ces conditions je préfère retourner d'où je viens : le C :-)
Tu peux utiliser la notation avec les opérateurs partout, mais aux endroits (rares en général) où le profiling a montré qu'il y avait problème de performance, te rabattre sur la notation add. C'est une micro-optimisation comme une autre.
décidément le C++ c'est pas mal, mais y'a trop de trucs ;-)
(*) Tiens, d'ailleurs, ça pourrait être drôle de faire un ioccc++, où l'on interdit l'obfuscation par préprocesseur, puisqu'il existe des trucs bien plus tordus en C++ :)
-- Loïc
Nicolas Aunai wrote:
Loïc Joly a exprimé avec précision :
vect &
vect::operator+(const vect &v) const
En général, on déclare l'opérateur + en dehors de la classe. Ceci pour
des raisons de symétrie (sinon, le premier terme doit être un vect, et
le deuxième un truc castable en vect, ce qui rompt la symétrie de
l'addition) (et on défini operator+ à partir de operator+=).
ah bon, tiens donc....
Ensuite, l'opérateur devrait retourner un objet, et non pas une
référence ou un pointeur. Ca peut poser des problèmes de performance,
puisque du coup l'objet va être copié,
en effet !
Mieux vaut un programme lent et correct qu'un programme rapide et faux.
mais ce problème peut être réduit :
- Certains compilateur implémentent la RVO (return value
optimisation), qui leur permet d'éviter une copie dans ce genre de cas.
mouais... j'aime pas trop qu'un code dépende d'un compilo
Le code n'en dépend pas, seule sa rapidité (à condition que tu aies joué
le jeu en définissant un constructeur de copie qui copie vraiment(*)).
Comme tout ce qui est de la rapidité d'ailleur. Tu n'est assuré de rien
en passant d'un compilo à l'autre en matière de performances.
- Il est possible de retourner non pas un vecteur mais un objet qui se
souvient de l'opération effectuée, et ne va réellement additionner que
quand on va accèder au contenu, tout en faisant cette gymnastique à la
compilation (voir par exemple blitz::tiny_vector sur
www.oonumerics.org, se munir d'une aspirine)
je sens le "trop compliqué" d'avance... :-(
Ca dépend d'où tu te place. Point de vue utilisateur, ça s'utilise de
façon transparente, point de vue implémenteur, c'est effectivement un
peu coton.
- Certains travaillent à founir au C++ une sémantique de déplacement
en plus de la sémantique de copie omniprésente actuellement. Si ton
programme peut attendre quelques années... ;)
nan :-)
Bon, dommage...
- Dans certains cas, une fonction void add (vect const &A, vect const
&B, vect &Result) peut aider, mais l'écriture n'est vraiment pas belle.
pas belle pas belle... c'est surtout qu'on perd l'intéret du C++ dans
l'affaire : les opérateurs surchargés... et dans ces conditions je
préfère retourner d'où je viens : le C :-)
Tu peux utiliser la notation avec les opérateurs partout, mais aux
endroits (rares en général) où le profiling a montré qu'il y avait
problème de performance, te rabattre sur la notation add. C'est une
micro-optimisation comme une autre.
décidément le C++ c'est pas mal, mais y'a trop de trucs ;-)
(*) Tiens, d'ailleurs, ça pourrait être drôle de faire un ioccc++, où
l'on interdit l'obfuscation par préprocesseur, puisqu'il existe des
trucs bien plus tordus en C++ :)
En général, on déclare l'opérateur + en dehors de la classe. Ceci pour des raisons de symétrie (sinon, le premier terme doit être un vect, et le deuxième un truc castable en vect, ce qui rompt la symétrie de l'addition) (et on défini operator+ à partir de operator+=).
ah bon, tiens donc....
Ensuite, l'opérateur devrait retourner un objet, et non pas une référence ou un pointeur. Ca peut poser des problèmes de performance, puisque du coup l'objet va être copié,
en effet !
Mieux vaut un programme lent et correct qu'un programme rapide et faux.
mais ce problème peut être réduit :
- Certains compilateur implémentent la RVO (return value optimisation), qui leur permet d'éviter une copie dans ce genre de cas.
mouais... j'aime pas trop qu'un code dépende d'un compilo
Le code n'en dépend pas, seule sa rapidité (à condition que tu aies joué le jeu en définissant un constructeur de copie qui copie vraiment(*)). Comme tout ce qui est de la rapidité d'ailleur. Tu n'est assuré de rien en passant d'un compilo à l'autre en matière de performances.
- Il est possible de retourner non pas un vecteur mais un objet qui se souvient de l'opération effectuée, et ne va réellement additionner que quand on va accèder au contenu, tout en faisant cette gymnastique à la compilation (voir par exemple blitz::tiny_vector sur www.oonumerics.org, se munir d'une aspirine)
je sens le "trop compliqué" d'avance... :-(
Ca dépend d'où tu te place. Point de vue utilisateur, ça s'utilise de façon transparente, point de vue implémenteur, c'est effectivement un peu coton.
- Certains travaillent à founir au C++ une sémantique de déplacement en plus de la sémantique de copie omniprésente actuellement. Si ton programme peut attendre quelques années... ;)
nan :-)
Bon, dommage...
- Dans certains cas, une fonction void add (vect const &A, vect const &B, vect &Result) peut aider, mais l'écriture n'est vraiment pas belle.
pas belle pas belle... c'est surtout qu'on perd l'intéret du C++ dans l'affaire : les opérateurs surchargés... et dans ces conditions je préfère retourner d'où je viens : le C :-)
Tu peux utiliser la notation avec les opérateurs partout, mais aux endroits (rares en général) où le profiling a montré qu'il y avait problème de performance, te rabattre sur la notation add. C'est une micro-optimisation comme une autre.
décidément le C++ c'est pas mal, mais y'a trop de trucs ;-)
(*) Tiens, d'ailleurs, ça pourrait être drôle de faire un ioccc++, où l'on interdit l'obfuscation par préprocesseur, puisqu'il existe des trucs bien plus tordus en C++ :)
-- Loïc
Loïc Joly
Nicolas Aunai wrote:
Il se trouve que Franck Branjonneau a formulé :
Pourquoi ne pas retourner le pointeur ?
pour savoir comment on fait avec les références, j'ai encore un peu de mal avec elles...
Lire par exemple l'article 31 (Item 31: Never return a reference to a local object or a dereferenced pointer initialized by new within the function.) de effective c++ de Meyers (et puis lire le reste du bouquin aussi ;))
mais ce n'est pas une bonne idée. Voir std::auto_ptr<>.
connait pas... je regarde
Bof, c'est hyper piègeur. J'aime pas du tout. Tu connais beaucoup de types comme ça :
int f(T c) { }
int main() { T a; T b(a); assert (a == b); // Et non...
Ou mieux utiliser le principe RAI et faire de x un pointeur sur vector.
RAI ?
RAII = Ressource acquisition is initialisation
En gros, dès que tu as besoin d'acquérir une ressouce (mémoire, handle, sémaphore...), tu le fais dans un contructeur, et tu la libère dans le destructeur ; ensuite, tu crées une variable locale du type correspondant. Intérêt premier : Tu es certain que la ressource sera libérée quoi qu'il arrive.
-- Loïc
Nicolas Aunai wrote:
Il se trouve que Franck Branjonneau a formulé :
Pourquoi ne pas retourner le pointeur ?
pour savoir comment on fait avec les références, j'ai encore un peu de
mal avec elles...
Lire par exemple l'article 31 (Item 31: Never return a reference to a
local object or a dereferenced pointer initialized by new within the
function.) de effective c++ de Meyers (et puis lire le reste du bouquin
aussi ;))
mais ce n'est pas une bonne idée. Voir std::auto_ptr<>.
connait pas... je regarde
Bof, c'est hyper piègeur. J'aime pas du tout. Tu connais beaucoup de
types comme ça :
int f(T c)
{
}
int main()
{
T a;
T b(a);
assert (a == b); // Et non...
Ou mieux
utiliser le principe RAI et faire de x un pointeur sur vector.
RAI ?
RAII = Ressource acquisition is initialisation
En gros, dès que tu as besoin d'acquérir une ressouce (mémoire, handle,
sémaphore...), tu le fais dans un contructeur, et tu la libère dans le
destructeur ; ensuite, tu crées une variable locale du type
correspondant. Intérêt premier : Tu es certain que la ressource sera
libérée quoi qu'il arrive.
pour savoir comment on fait avec les références, j'ai encore un peu de mal avec elles...
Lire par exemple l'article 31 (Item 31: Never return a reference to a local object or a dereferenced pointer initialized by new within the function.) de effective c++ de Meyers (et puis lire le reste du bouquin aussi ;))
mais ce n'est pas une bonne idée. Voir std::auto_ptr<>.
connait pas... je regarde
Bof, c'est hyper piègeur. J'aime pas du tout. Tu connais beaucoup de types comme ça :
int f(T c) { }
int main() { T a; T b(a); assert (a == b); // Et non...
Ou mieux utiliser le principe RAI et faire de x un pointeur sur vector.
RAI ?
RAII = Ressource acquisition is initialisation
En gros, dès que tu as besoin d'acquérir une ressouce (mémoire, handle, sémaphore...), tu le fais dans un contructeur, et tu la libère dans le destructeur ; ensuite, tu crées une variable locale du type correspondant. Intérêt premier : Tu es certain que la ressource sera libérée quoi qu'il arrive.
-- Loïc
Franck Branjonneau
Nicolas Aunai écrivait:
Il se trouve que Franck Branjonneau a formulé :
Mais je doute que p->x.size() soit non nul. Utilise
*(p->at(i)) = (*x[i] + *(v.x[i]));
ok mon vector sera vide... mais pourquoi utiliser at() ? si mon vector est vide je devrai plutôt utiliser :
p->x->push_back((*x[i] + *(v.x[i])));
non ?
Oui. Mais tu t'interrogeais sur ta boucle. at() te fournissait la réponse. -- Franck Branjonneau
Nicolas Aunai <nicolas.aunai@free.fr> écrivait:
Il se trouve que Franck Branjonneau a formulé :
Mais je doute que p->x.size() soit non nul. Utilise
*(p->at(i)) = (*x[i] + *(v.x[i]));
ok mon vector sera vide... mais pourquoi utiliser at() ? si mon vector
est vide je devrai plutôt utiliser :
p->x->push_back((*x[i] + *(v.x[i])));
non ?
Oui. Mais tu t'interrogeais sur ta boucle. at() te fournissait la réponse.
--
Franck Branjonneau <fasbjx@free.fr>
Ou encore boost::scoped_ptr<Type> foo(); // Propriété unique, copies interdites
Voire même monNamespaceAMoi::value_ptr<Type> foo(); // Propriété unique duplication lors d'une copie
-- Loïc
kanze
Loïc Joly wrote in message news:<cbcn6c$eee$...
Nicolas Aunai wrote:
[...]
RAI ?
RAII = Ressource acquisition is initialisation
En gros, dès que tu as besoin d'acquérir une ressouce (mémoire, handle, sémaphore...), tu le fais dans un contructeur, et tu la libère dans le destructeur ; ensuite, tu crées une variable locale du type correspondant. Intérêt premier : Tu es certain que la ressource sera libérée quoi qu'il arrive.
C'est bien l'origine du nom, mais l'important n'est pas d'acquérir la ressource dans le construteur. L'important dans l'idiome, c'est que la ressource appartient à une classe dont le destructeur le libère, et ça, dès que la ressource est acquise. Je considèrerais les boost::shared_ptr et al. comme un exemple de RAII, mais la ressournce en question (la mémoire) n'est pas acquise dans le constructeur.
-- 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
Loïc Joly <loic.actarus.joly@wanadoo.fr> wrote in message
news:<cbcn6c$eee$1@news-reader5.wanadoo.fr>...
Nicolas Aunai wrote:
[...]
RAI ?
RAII = Ressource acquisition is initialisation
En gros, dès que tu as besoin d'acquérir une ressouce (mémoire,
handle, sémaphore...), tu le fais dans un contructeur, et tu la libère
dans le destructeur ; ensuite, tu crées une variable locale du type
correspondant. Intérêt premier : Tu es certain que la ressource sera
libérée quoi qu'il arrive.
C'est bien l'origine du nom, mais l'important n'est pas d'acquérir la
ressource dans le construteur. L'important dans l'idiome, c'est que la
ressource appartient à une classe dont le destructeur le libère, et ça,
dès que la ressource est acquise. Je considèrerais les boost::shared_ptr
et al. comme un exemple de RAII, mais la ressournce en question (la
mémoire) n'est pas acquise dans le constructeur.
--
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
En gros, dès que tu as besoin d'acquérir une ressouce (mémoire, handle, sémaphore...), tu le fais dans un contructeur, et tu la libère dans le destructeur ; ensuite, tu crées une variable locale du type correspondant. Intérêt premier : Tu es certain que la ressource sera libérée quoi qu'il arrive.
C'est bien l'origine du nom, mais l'important n'est pas d'acquérir la ressource dans le construteur. L'important dans l'idiome, c'est que la ressource appartient à une classe dont le destructeur le libère, et ça, dès que la ressource est acquise. Je considèrerais les boost::shared_ptr et al. comme un exemple de RAII, mais la ressournce en question (la mémoire) n'est pas acquise dans le constructeur.
-- 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