Supposons que j'aie le constructeur suivant dans une classe C++ :
MyClass::MyClass()
{
char* buffer = malloc(100);
if (0 != someD3DXCallThatCanFail(..., buffer, ...))
{
free(buffer);
throw MyException(L"some message");
}
char* buffer2 = malloc(200);
if (0 != anotherD3DCallThatCanFail(..., buffer2, ...))
{
free(buffer);
free(buffer2);
throw MyException(L"another message");
}
.. more code here where buffer and buffer2 are still used
free(buffer);
free(buffer2);
}
EDIT : Je déteste malloc/free et new/delete, mais malheureusement j'ai besoin d'utiliser des buffers pour charger des textures qui sont ensuite transmises à ID3D10ShaderResourceView, ID3D10Buffer, vertex buffer et autres. Tous ces éléments nécessitent des pointeurs vers un tampon.
Ce que j'essaie de faire, c'est d'utiliser des exceptions au lieu de renvoyer des codes d'erreur. Je souhaite également créer des tampons là où ils sont nécessaires et les libérer dès qu'ils ne sont plus nécessaires.
Cependant, ce qui est moche, c'est qu'en cas d'erreur, que je renvoie des codes d'erreur ou que je lève des exceptions, je ne dois pas oublier de nettoyer le tampon qui a été créé jusqu'à ce moment-là. Si j'ai 10 tampons et 10 points d'erreur possibles, je devrai appeler free() 100 fois (dans chaque cas d'erreur, n'oubliez pas de libérer chaque tampon).
Supposons maintenant que je veuille, ou pire, que mon collègue veuille modifier la logique et, par exemple, ajouter un autre tampon quelque part au milieu. Il devra alors examiner toutes les erreurs qui peuvent se produire dans le reste de la méthode et ajouter free() pour ce tampon à chacun de ces endroits. S'il est pressé, il peut facilement négliger quelques endroits de ce type, et vous avez une fuite de mémoire.
Le code s'en trouve considérablement alourdi.
Enfin, un mot-clé résoudrait ce problème en Java ou en C#. Quel que soit l'endroit du code où l'exception s'est produite, je nettoierais toujours tous ces tampons dans "finally" (entre parenthèses, vous n'en auriez pas besoin avec le garbage collection). En C++, d'après ce que j'ai compris, je devrais peut-être créer une variable membre pour chacun de ces tampons, et dans le destructeur, m'assurer que les tampons sont nettoyés. Cela me semble également assez laid, car une variable membre avec le nom "pBuffer", même privée, n'est qu'un déchet, puisqu'elle n'est utilisée que dans une seule méthode (dans ce cas, le constructeur) et qu'elle sera toujours NULL le reste du temps.
Il doit s'agir d'un problème courant, mais je n'ai pas réussi à trouver de réponse à l'aide de la recherche. Je vous remercie de votre attention.