La version classique de new lance une exception si il y a un problème (allocation ou construction), si elle n'est pas du tout attrapé, alors le programme termine.
Si l'ensemble déclaration de la variable, appel à new et affectation à la variable est dans un bloc try avec un catch qui attrape cette exception, alors la question ne se pose pas, en cas d'exception une fois attrapée cette variable n'existe plus.
1 2 3 4 5 6 7 8 9
|
try{
//...
A* p(0);
//...
p = new A(/*param*/);
//...
} catch(/*exceptions*/)
{ /*...*/ } |
Si l'ensemble appel à new et l’affectation à la variable est dans dans le try (qui attrape les exceptions concernées), alors l'ordre entre construction et affectation n'étant pas définie, on ne peut rien dire de la valeur de la variable après le bloc catch.
1 2 3 4 5 6 7 8 9 10
|
A* p(0);
//...
try{
//...
p = new A(/*param*/);
//...
) catch(/*exceptions*/)
{ /*...*/ }
//ici on ne peut rien dire de p. |
NB: Dans ce cas ce sont les exceptions provenant des constructeurs qui posent problèmes, si ils ne peuvent lancer, alors la valeur de p sera non nulle.
On peut tricher un peu en utilisant une variable intermédiaire pour "forcer" l'ordre entre la construction et l'affectation à la variable :
1 2 3 4 5 6 7 8 9 10
|
A* p(0);
//...
try{
//...
A* q = new A(/*param*/);
p = q;
//...
) catch(/*exceptions*/)
{ /*...*/ } |
Sans prendre en compte les éventuels optimisations des compilateurs, à la sortie de ce code on a bien p qui vaut 0 ou est associé à l'objet alloué et construit avant.
Malheureusement, il est fort probable que le compilateur optimise un tel code (ie il considère que la variable q ne sert à rien).
NB: Ces morceaux de code n'ont de sens qu'avec les règles de programmation qui te sont imposées, ils ne servent à rien dans un contexte normal (les exceptions font leur boulot).
Partager