Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

auto_ptr

17 réponses
Avatar
Jean-Marc Bourguet
Juste pour lever un doute en attendant que j'ai mes références sous la
main.

f(std::auto_ptr<T> x, std::auto_ptr<T> y);

f(new T(...), new T(...));

est bien un risque si T::T(...) peut jeter une exception.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

10 réponses

1 2
Avatar
Gabriel Dos Reis
Jean-Marc Bourguet writes:

| Juste pour lever un doute en attendant que j'ai mes références sous la
| main.
|
| f(std::auto_ptr<T> x, std::auto_ptr<T> y);
|
| f(new T(...), new T(...));
|
| est bien un risque si T::T(...) peut jeter une exception.

Tout à fait. Je crois que Herb a fait de ça un GotW. James semble
l'affectionner pour émettre ses plus véhémentes protestations.

-- Gaby
Avatar
Jean-Marc Bourguet
Gabriel Dos Reis writes:

Jean-Marc Bourguet writes:

| Juste pour lever un doute en attendant que j'ai mes références sous la
| main.
|
| f(std::auto_ptr<T> x, std::auto_ptr<T> y);
|
| f(new T(...), new T(...));
|
| est bien un risque si T::T(...) peut jeter une exception.

Tout à fait. Je crois que Herb a fait de ça un GotW.


A priori

template <typename T, typename P1, typename P2>
std::auto_ptr<T> allocate(P1 const& p1, P2 const& p2)
{
return new T(p1, p2);
}

f(allocate<T>(...), allocate<T>(...));

devrait résoudre le problème, non?

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
James Kanze
Gabriel Dos Reis writes:

|> Jean-Marc Bourguet writes:

|> | Juste pour lever un doute en attendant que j'ai mes
|> | références sous la main.

|> | f(std::auto_ptr<T> x, std::auto_ptr<T> y);

|> | f(new T(...), new T(...));

|> | est bien un risque si T::T(...) peut jeter une exception.

|> Tout à fait. Je crois que Herb a fait de ça un GotW. James
|> semble l'affectionner pour émettre ses plus véhémentes
|> protestations.

Tu pourrais t'expliquer ? Je suis tout à fait d'accord qu'il y a
une risque, importante. C'est une des raisons pourquoi je
préfèrerais qu'on définisse mieux l'ordre d'évaluation des
expressions ; c'est un piège assez subtile. (Si Herb en a fait un
GotW, c'est parce que Dave Abraham s'y est tombé dans un de ses
postings. Et si des gens de ce niveau y tombe, pense aux risques pour
les autres.)

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
Avatar
Gabriel Dos Reis
Jean-Marc Bourguet writes:

| Gabriel Dos Reis writes:
|
| > Jean-Marc Bourguet writes:
| >
| > | Juste pour lever un doute en attendant que j'ai mes références sous la
| > | main.
| > |
| > | f(std::auto_ptr<T> x, std::auto_ptr<T> y);
| > |
| > | f(new T(...), new T(...));
| > |
| > | est bien un risque si T::T(...) peut jeter une exception.
| >
| > Tout à fait. Je crois que Herb a fait de ça un GotW.
|
| A priori
|
| template <typename T, typename P1, typename P2>
| std::auto_ptr<T> allocate(P1 const& p1, P2 const& p2)
| {
| return new T(p1, p2);
| }
|
| f(allocate<T>(...), allocate<T>(...));
|
| devrait résoudre le problème, non?

Je ne vois pas comment. Peux-tu préciser ?

-- Gaby
Avatar
Michaël Monerau
Jean-Marc Bourguet wrote:
Juste pour lever un doute en attendant que j'ai mes références sous la
main.

f(std::auto_ptr<T> x, std::auto_ptr<T> y);

f(new T(...), new T(...));

est bien un risque si T::T(...) peut jeter une exception.


Pourrais-tu expliquer pourquoi il y a un risque ?
--
<-= Michaël "Cortex" Monerau =->

Avatar
Gabriel Dos Reis
James Kanze writes:

| Gabriel Dos Reis writes:
|
| |> Jean-Marc Bourguet writes:
|
| |> | Juste pour lever un doute en attendant que j'ai mes
| |> | références sous la main.
|
| |> | f(std::auto_ptr<T> x, std::auto_ptr<T> y);
|
| |> | f(new T(...), new T(...));
|
| |> | est bien un risque si T::T(...) peut jeter une exception.
|
| |> Tout à fait. Je crois que Herb a fait de ça un GotW. James
| |> semble l'affectionner pour émettre ses plus véhémentes
| |> protestations.
|
| Tu pourrais t'expliquer ? Je suis tout à fait d'accord qu'il y a
| une risque, importante. C'est une des raisons pourquoi je
| préfèrerais qu'on définisse mieux l'ordre d'évaluation des
| expressions ; c'est un piège assez subtile. (Si Herb en a fait un
| GotW, c'est parce que Dave Abraham s'y est tombé dans un de ses
| postings. Et si des gens de ce niveau y tombe, pense aux risques pour
| les autres.)

Tu viens juste de donner un autre exemple de ce que je disais.

-- Gaby
Avatar
Jean-Marc Bourguet
Gabriel Dos Reis writes:

Jean-Marc Bourguet writes:

| Gabriel Dos Reis writes:
|
| > Jean-Marc Bourguet writes:
| >
| > | Juste pour lever un doute en attendant que j'ai mes références sous la
| > | main.
| > |
| > | f(std::auto_ptr<T> x, std::auto_ptr<T> y);
| > |
| > | f(new T(...), new T(...));
| > |
| > | est bien un risque si T::T(...) peut jeter une exception.
| >
| > Tout à fait. Je crois que Herb a fait de ça un GotW.
|
| A priori
|
| template <typename T, typename P1, typename P2>
| std::auto_ptr<T> allocate(P1 const& p1, P2 const& p2)
| {
| return new T(p1, p2);
| }
|
| f(allocate<T>(...), allocate<T>(...));
|
| devrait résoudre le problème, non?

Je ne vois pas comment. Peux-tu préciser ?


Le problème dans

f(new T(...), new T(...));

est, si je ne me trompe, que l'exécution peux se dérouler

new T(...)
new T(...)
std::auto_ptr()
std::auto_ptr()
f()

si le deuxième contructeur jette une exception, on a un objet qui
n'est plus référencable avec les problèmes potentiels qui s'en
suivent.

Si on utilise allocate, l'exécution se passe

allocate()
allocate()
f()

si le deuxième constructeur de T jette une exception, le résultat du
premier est déjà encapsulé dans un auto_ptr donc celui-ci est détruit
et l'objet qui n'était plus référencable dans le premier cas est
détruit aussi et sa mémoire libérée. A moins qu'il soit permis
d'entrelacer l'exécution de deux fonctions?

On pourrait même s'amuser à faire du allocate un membre template du
pointeur intelligent, (le constructeur serait amusant mais interdirait
d'utiliser le constructeur par défaut ou un constructeur prenant un
pointeur intelligent du même type).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Benoit Dejean
Le Sun, 13 Jul 2003 15:03:40 +0200, Jean-Marc Bourguet a écrit :


Juste pour lever un doute en attendant que j'ai mes références sous la
main.

f(std::auto_ptr<T> x, std::auto_ptr<T> y);

f(new T(...), new T(...));

est bien un risque si T::T(...) peut jeter une exception.

A+


pourquoi ne passes tu pas par des variables ?

std::auto_ptr<T> x(new T())
std::auto_ptr<T> y(new T())

f(x, y)

--
"Ne perdez pas de vue qu'un programme rapide
et incorrect est d'une utilité presque nulle."
Ce qui est loin d'être incompatible avec la notion d'Art.

Avatar
James Kanze
Jean-Marc Bourguet writes:

|> Gabriel Dos Reis writes:

|> > Jean-Marc Bourguet writes:

|> > | Juste pour lever un doute en attendant que j'ai mes
|> > | références sous la main.

|> > | f(std::auto_ptr<T> x, std::auto_ptr<T> y);

|> > | f(new T(...), new T(...));

|> > | est bien un risque si T::T(...) peut jeter une exception.

|> > Tout à fait. Je crois que Herb a fait de ça un GotW.

|> A priori

|> template <typename T, typename P1, typename P2>
|> std::auto_ptr<T> allocate(P1 const& p1, P2 const& p2)
|> {
|> return new T(p1, p2);
|> }

|> f(allocate<T>(...), allocate<T>(...));

|> devrait résoudre le problème, non?

Certes, à condition que ton constructeur prend deux paramètres.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
Avatar
James Kanze
Gabriel Dos Reis writes:

|> Jean-Marc Bourguet writes:

|> | Gabriel Dos Reis writes:

|> | > Jean-Marc Bourguet writes:

|> | > | Juste pour lever un doute en attendant que j'ai mes
|> | > | références sous la main.

|> | > | f(std::auto_ptr<T> x, std::auto_ptr<T> y);

|> | > | f(new T(...), new T(...));

|> | > | est bien un risque si T::T(...) peut jeter une exception.

|> | > Tout à fait. Je crois que Herb a fait de ça un GotW.

|> | A priori

|> | template <typename T, typename P1, typename P2>
|> | std::auto_ptr<T> allocate(P1 const& p1, P2 const& p2)
|> | {
|> | return new T(p1, p2);
|> | }

|> | f(allocate<T>(...), allocate<T>(...));

|> | devrait résoudre le problème, non?

|> Je ne vois pas comment. Peux-tu préciser ?

Parce que chaque allocation et son affectation à un auto_ptr se
fait dans une fonction à part, et le compilateur n'a pas le droit
de melanger les fonctions -- une fois qu'il commence une fonction, il
faut qu'il le finisse avant de continuer dans l'expression appelante.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
1 2