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

Exception dans les paramètres d'un constructeur

24 réponses
Avatar
Marc G
Je m'explique
j'ai un code du genre

X * une_fontion(void)
{
try {
return new X( f());
}
catch(...)
{
return new X();
}
}

Ma question : si f() lance une exception, est-ce que j'ai un problème de
perte de mémoire ?
je pense que les paramètres du constructeur sont évalués avant "l'appel"
proprement dit du constructeur et que l'allocation mémoire n'est pas
réalisée lorsque l'exception est levée. Mais je préfère avoir l'avis
d'experts :-)
Merci à ceux qui ne sont pas en vacances.
Marc

10 réponses

1 2 3
Avatar
Alain Gaillard
C'est beaucoup plus verbeux,


Oui.
Question de goût. Je préfère un code clairement découpé en séquence.
Bien sur, si f() construit un objet, on peut reprocher la construction
éventuelle d'un temporaire. Mais ce n'était pas la question qui portait
une levée d'exception.

ça oblige de connaître le type de retour,


J'espère bien. C'est toujours bon de savoir ce qu'on fait.

et ça empêche les move semantics [...]


C'est où ça dans le standard ?

Sans parler du fait qu'il faut faire attention à la portée de la
variable qui détermine sa durée de vie, etc.


S'il y a problème à ce niveau, c'est qu'il y a problème dans la
classe X.


Bref, c'est totalement stupide.


Trop aimable :)

Au fait tu dis "Sans parler du fait qu'il faut faire attention à la
portée de la variable qui détermine sa durée de vie, etc."
Donc tu dis qu'avec return new X( f()); la question ne se pose pas,
n'est-ce pas ? Je te comprends peut être mal, mais je me demande quand
même si par hasard tu n'aurais pas un peu dit quelque chose de
stupide là...
:-O

--
Alain

Avatar
Sylvain
Alain Gaillard wrote on 29/08/2007 17:17:

Bref, c'est totalement stupide.


[...] Je te comprends peut être mal, mais je me demande quand
même si par hasard tu n'aurais pas un peu dit quelque chose de
stupide là...


ou même peut-être de totalement stupide ?!...

Sylvain.


Avatar
Alain Gaillard
Salut Sylvain :)


ou même peut-être de totalement stupide ?!...


J'osais pas le dire :)

--
Alain

Avatar
Mathias Gaunard
C'est beaucoup plus verbeux,


Oui.
Question de goût. Je préfère un code clairement découpé en séquence.
Bien sur, si f() construit un objet, on peut reprocher la construction
éventuelle d'un temporaire. Mais ce n'était pas la question qui portait
une levée d'exception.

ça oblige de connaître le type de retour,


J'espère bien. C'est toujours bon de savoir ce qu'on fait.


Sauf que quand il y a des templates en jeu, par exemple, des fois tu ne
peux tout simplement pas le savoir.
Ou alors le type retourné est un détail d'implémentation (cas de
std::tr1::bind, par exemple).

Bien sûr, il est toujours possible d'utiliser typeof, decltype ou auto.
À noter que typeof et auto enlèvent les références, et que seul auto
n'est pas verbeux.
Et tu as toujours les problèmes sous-mentionnés.


et ça empêche les move semantics [...]


C'est où ça dans le standard ?


C'est une nouveauté.
Ce serait pas mal, accessoirement, de se tenir au courant des évolutions
du langage.
Surtout quand elles sont aussi majeures.


Sans parler du fait qu'il faut faire attention à la portée de la
variable qui détermine sa durée de vie, etc.


S'il y a problème à ce niveau, c'est qu'il y a problème dans la
classe X.


L'objet temporaire sera détruit dès que l'appel à la fonction sera terminé.
Bref, il n'existera que le temps de son utilisation.

Alors que si tu créés une variable s'étendant à toute la portée
courante, et comme en général la portée est plus grande que la période
d'utilité réelle de la variable dans une programmation de type
séquentielle comme tu aimes (ce qui est complètement désuet, d'ailleurs
-- on préfère beaucoup plus favoriser la programmation fonctionnelle de
nos jours, pour plusieurs raisons, aussi bien de performance que de
validité et maintenabilité) alors tu pollues l'espace tout un intégrant
certaines incohérences sémantiques. (en effet, la portée n'a pas a
assumer la propriété de l'objet puisque celui devrait être temporaire)


Trop aimable :)


Je n'ai en effet pas la réputation d'être aimable.


Au fait tu dis "Sans parler du fait qu'il faut faire attention à la
portée de la variable qui détermine sa durée de vie, etc."
Donc tu dis qu'avec return new X( f()); la question ne se pose pas,


La question ne se pose pas puisque idéalement personne ne devrait jamais
écrire du code pareil.

Dans du beau code orienté sémantiques de valeur, on n'utilise new que
dans l'implémentation de constructeurs, où éventuellement dans d'autres
détails d'implémentation.
Quoi qu'il en soit, rien de tel ne devrait être exposé.

Dans du code orienté sémantiques d'entité, mieux vaut choisir d'utiliser
partout un type de shared_ptr.
Il y a des travaux en cours dans le standard pour avoir ce genre de
chose sans exposer 'new'.

À noter que je ne suis personnellement pas un fan de shared_ptr, ni des
sémantiques d'entité et du partage global en général.


Avatar
Alain Gaillard
Sauf que quand il y a des templates en jeu,


Où sont les templates dans la question originale ?

C'est où ça dans le standard ?


C'est une nouveauté.
Ce serait pas mal, accessoirement, de se tenir au courant des
évolutions du langage.
Surtout quand elles sont aussi majeures.



Je suis au courant et je ne vois rien de tel dans mon standard "actuel".


d'ailleurs -- on préfère beaucoup plus favoriser la programmation
fonctionnelle de nos jours,


Ce qu'on préfère de nos jours n'est pas forcément toujours avisé.
Comme par exemple la mode actuelle de mettre des templates partout où il
n'y en a pas besoin.
Pour faire de la programmation fonctionnelle je préfère un langage
fonctionnel. Comme Haskell par exemple. C++ n'est pas un langage
fonctionnel et n'a pas vocation à l'être, même si on peut il est vrai
faire pas mal de belles choses.

pour plusieurs raisons, aussi bien de
performance que de validité et maintenabilité) alors tu pollues
l'espace tout un intégrant certaines incohérences sémantiques. (en
effet, la portée n'a pas a assumer la propriété de l'objet puisque
celui devrait être temporaire)


Je ne vois en quoi tout ce discours indigeste présente le moindre
intérêt car le cas où le contructeur de X est écrit convenablement

X(const TypeTruc&);

Et je ne vois toujours pas en quoi "il faut faire attention à la portée de la
variable"
Surtout ne perds pas ton ton à essayer de me faire voir.

Je n'ai en effet pas la réputation d'être aimable.


Ben à voir comment tu penses quand tu programmes, on se rend bien compte
que ceci explique cela :)
Ca me fait 2 bonnes raisons de ne pas pousser la discussion avec toi un
post plus loin.

Dans du beau code orienté sémantiques de valeur, on n'utilise new que
dans l'implémentation de constructeurs,


Soit. Je te l'accorde volontiers. Quel rapport, stricto sensu, avec la
question ? Et quel rapport même avec ce que tu as dis si aimablement
hier, en commentant mon post ?
Je ne pense pas avoir validé (en tout cas je n'ai pas voulu le faire) la
présence de new dans le code du PO. J'ai simplement parlé de découper
le code en séquences. Ni plus ni moins.


Dans du code orienté sémantiques d'entité, mieux vaut choisir
d'utiliser partout un type de shared_ptr.


C'est sans doute très vrai. Mais encore une fois quel rapport avec la
question du PO ?

À noter que je ne suis personnellement pas un fan de shared_ptr, ni des
sémantiques d'entité et du partage global en général.


Moi non plus.

Bon je te laisse (définitivement) à tes réfléxions (trop) profondes.
J'espère quand même pour elles que les mouches qui habitent chez toi
sont abondamment approvisionnées en vaseline, les pauvres :)

--
Alain


Avatar
Alain Gaillard
Et je ne vois toujours pas en quoi "il faut faire attention à la portée de la
variable"
Surtout ne perds pas ton ton à essayer de me faire voir.

Je n'ai en effet pas la réputation d'être aimable.


Ben à voir comment tu penses quand tu programmes, on se rend bien compte
que ceci explique cela :)
Ca me fait 2 bonnes raisons de ne pas pousser la discussion avec toi un
post plus loin.

Dans du beau code orienté sémantiques de valeur, on n'utilise new que
dans l'implémentation de constructeurs,


Soit. Je te l'accorde volontiers. Quel rapport, stricto sensu, avec la
question ? Et quel rapport même avec ce que tu as dis si aimablement
hier, en commentant mon post ?
Je ne pense pas avoir validé (en tout cas je n'ai pas voulu le faire) la
présence de new dans le code du PO. J'ai simplement parlé de découper
le code en séquences. Ni plus ni moins.


Dans du code orienté sémantiques d'entité, mieux vaut choisir
d'utiliser partout un type de shared_ptr.


C'est sans doute très vrai. Mais encore une fois quel rapport avec la
question du PO ?

À noter que je ne suis personnellement pas un fan de shared_ptr, ni des
sémantiques d'entité et du partage global en général.


Moi non plus.

Bon je te laisse (définitivement) à tes réfléxions (trop) profondes.
J'espère quand même pour elles que les mouches qui habitent chez toi
sont abondamment approvisionnées en vaseline, les pauvres :)

--
Alain

Avatar
Alain Gaillard
Le Thu, 30 Aug 2007 15:31:57 +0200, Mathias Gaunard a écrit :

Sauf que quand il y a des templates en jeu, par exemple,


Et où sont ils ces templates dans la question du PO ?

C'est une nouveauté.
Ce serait pas mal, accessoirement, de se tenir au courant des évolutions
du langage.
Surtout quand elles sont aussi majeures.


Je suis au courant et je ne vois rien de tel dans mon standard actuel.

-- on préfère beaucoup plus favoriser la programmation fonctionnelle de
nos jours, pour plusieurs raisons,


Ce que l'on préfère de nos jours n'est pas forcément pertinent, ni ne
fait force de loi. On préfère aussi mettre des templates partout là où
il n'y en a pas besoin, etc.

En ce qui concerne la programmation fonctionnelle, quand je veux
en faire je prends un langage fonctionnel. Un vrai. Haskell tiens par
exemple. C++ n'a pas vocation à être un langage fonctionnel même si on
peut il est vrai faire pas même de belles choses.

aussi bien de performance que de
validité et maintenabilité) alors tu pollues l'espace tout un intégrant
certaines incohérences sémantiques. (en effet, la portée n'a pas a
assumer la propriété de l'objet puisque celui devrait être temporaire)


Je ne vois pas en quoi ce discours indigeste présente le moindre intérêt.
Surtout si le constructeur de X est écrit convenablement

X(const TypeTruc&);

Et je ne vois toujours pas en quoi "il faut faire attention à la portée de la
variable"
Surtout ne perds pas ton temps à essayer de me faire voir.

Je n'ai en effet pas la réputation d'être aimable.


Ben à voir comment tu penses quand tu programmes, on se rend bien compte
que ceci explique cela :)
Ca me fait 2 bonnes raisons de ne pas pousser la discussion avec toi un
post plus loin.

Dans du beau code orienté sémantiques de valeur, on n'utilise new que
dans l'implémentation de constructeurs,


Soit. Je te l'accorde volontiers. Quel rapport, stricto sensu, avec la
question ? Et quel rapport même avec ce que tu as dis si aimablement
hier, en commentant mon post ?
Je ne pense pas avoir validé (en tout cas je n'ai pas voulu le faire) la
présence de new dans le code du PO. J'ai simplement parlé de découper
le code en séquences. Ni plus ni moins.

Dans du code orienté sémantiques d'entité, mieux vaut choisir
d'utiliser partout un type de shared_ptr.


C'est sans doute très vrai. Mais encore une fois quel rapport avec la
question du PO ?

À noter que je ne suis personnellement pas un fan de shared_ptr, ni des
sémantiques d'entité et du partage global en général.


Moi non plus.

Bon je te laisse (définitivement) à tes réfléxions (trop) profondes.
J'espère quand même pour elles que les mouches qui habitent chez toi
sont abondamment approvisionnées en vaseline, les pauvres :)

--
Alain

--
Alain

Avatar
Michael DOUBEZ
Sauf que quand il y a des templates en jeu,


Où sont les templates dans la question originale ?

C'est où ça dans le standard ?
C'est une nouveauté.

Ce serait pas mal, accessoirement, de se tenir au courant des
évolutions du langage.
Surtout quand elles sont aussi majeures.



Je suis au courant et je ne vois rien de tel dans mon standard "actuel".



Oui, AMA aucune raison que ça empêche le move sémantique bien que si on
peut créer une variable intermédiaire alors le move sémantique perd
quand même de son intérêt (i.e. résolution du forwarding problem).

[snip]


Bon je te laisse (définitivement) à tes réfléxions (trop) profondes.
J'espère quand même pour elles que les mouches qui habitent chez toi
sont abondamment approvisionnées en vaseline, les pauvres :)


Bien sûr que les mouches sont bien graissées sinon elles ne flottent as
à la surface de l'eau et on attrape pas de poisson.
Mais ce genre de discussion devrait être réservé à fr.alt.pêche ou un
autre groupe à vocation piscicole.

Michael



Avatar
Mathias Gaunard

Je suis au courant et je ne vois rien de tel dans mon standard "actuel".


Ton standard actuel distingue déjà lvalue et rvalue, variables nommées
et variables temporaires.



Ce qu'on préfère de nos jours n'est pas forcément toujours avisé.
Comme par exemple la mode actuelle de mettre des templates partout où il
n'y en a pas besoin.


Les templates sont sans aucun doute la fonctionnalité la plus
intéressante de C++.
Cela permet le polymorphisme paramétrique, comme dans les langages ML
par exemple, et quelques bonus (méta-programmation etc.)

Les concepts permettent de vérifier qu'un type vérifie une interface, et
ce sans que le type lui-même ait à indiquer qu'il implémente cette
interface.
Ce qui est hautement plus pratique que les interfaces de l'orienté objet.

L'orienté objet, qui constitue une alternative, est avec son héritage,
sa coercion et son polymorphisme d'inclusion un paradigme bien moins
intéressant. Son seul intérêt est qu'il peut supporter le dynamisme --
d'une manière assez peu flexible d'ailleurs, mais bon, elle a le mérite
d'être relativement performante.
(Il se trouve en général en plus que l'utilisation de l'orienté objet
est aussi synonyme de mauvaise gestion de ressources, en particulier
mémoire)


Pour faire de la programmation fonctionnelle je préfère un langage
fonctionnel. Comme Haskell par exemple. C++ n'est pas un langage
fonctionnel et n'a pas vocation à l'être


Le C++ supporte parfaitement le paradigme fonctionnel -- on pourrait
dire que l'absence de ramasse-miettes ne permet pas de faire de vraies
closures, mais je trouve personnellement mieux cela ainsi --, et de
nombreux composants de la bibliothèque standard sont basés sur ce paradigme.


Je ne vois en quoi tout ce discours indigeste présente le moindre
intérêt car le cas où le contructeur de X est écrit convenablement

X(const TypeTruc&);


Je ne vois pas le rapport.


Et je ne vois toujours pas en quoi "il faut faire attention à la portée de la
variable"
Surtout ne perds pas ton ton à essayer de me faire voir.


Tu n'as pas du tout comprendre, donc.
En étendant la portée, tu étends la durée de vie. Une variable qui
devrait n'être que temporaire ne devrait pas avoir une durée de vie
rallongée pour que tu puisses plus facilement t'y retrouver.

Je ne continuerai pas à t'expliquer : si tu ne veux pas comprendre,
c'est tout choix.
J'aurais néanmoins pensé qu'un homme pragmatique tel que toi attacherait
plus d'importance aux soucis liés au rvalue references etc.


Je ne pense pas avoir validé (en tout cas je n'ai pas voulu le faire) la
présence de new dans le code du PO.


C'est toi qui m'a posé la question avec une question qui renvoie un
pointeur alloué avec new, ce qui constitue une horreur innommable. J'ai
donc rédigé ceci pour t'instruire des méthodes de base de la
programmation en C++ qui permettent d'éviter cela.

Avatar
Alain Gaillard

Bien sûr que les mouches sont bien graissées sinon elles ne flottent as
à la surface de l'eau et on attrape pas de poisson.


Lol.


--
Alain

1 2 3