Bonjour à tous,
Après quelques recherches sur internet, je me pose toujours une question sur le mécanisme de gestion des exceptions dans les constructeurs décrit dans le cours de Christian Casteyde : http://www.developpez.com/c/megacours/x3910.html
J'ai considéré le cas suivant :
A l'exécution, on obtient ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 #include <iostream> using namespace std; void Print(const string &inStr) { cout << inStr << endl; } struct A { double *valA; A() try : valA(0) { valA = new double; Print("A::A()"); throw new string("Exception !"); } catch(...) { Print("Catch de A"); delete valA; valA = 0; // Pas de problème: valA vaut 0 ou pointe sur une zone mémoire correctement allouée. } }; struct B : public A { double *valB; B() try : valB(0), A() { valB = new double; Print("B::B()"); } catch(...) { Print("Catch de B"); if(valB) Print(string("valB != 0")) ; else Print(string("valB == 0")); delete valB; valB = 0; // Aïe, aïe ! Dans ce cas, valB n'a pas encore été initialisé à 0, il pointe vers une zone mémoire farfelue ! } }; int main() { try { B b; } catch(string *inE) { Print(*inE); } }
Dans cet exemple, le code du constructeur de B ne sera jamais exécuté et le pointeur valB n'est jamais initialisé à zéro. Pourtant, le catch de B sera exécuté. Or j'aimerais pouvoir libérer le membre valB dans ce catch. Je ne peux pas me contenter d'appeler "delete valB" sans me poser de question puisque dans le cas de cet exemple, valB n'est pas initialisé à zéro !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 A::A() Catch de A Catch de B valB != 0 Exception !
En fouillant dans la FAQ, j'ai vu qu'une autre méthode (à laquelle j'avais pensé) y était proposée : http://c.developpez.com/faq/cpp/?pag...S_constructeur
Cette second méthode marche bien : le catch d'une classe est appelé si et seulement si le constructeur de cette classe a été exécuté (éventuellement partiellement). Les classes dérivées ne seront pas averties de l'exception.
Je me pose donc la question naturelle suivante : le C++ propose un mécanisme censé être adapté aux exceptions dans les constructeurs mais il ne me paraît pas utilisable. Est-ce que je l'utilise mal ? Comment procédez-vous pour gérer les exceptions dans les constructeurs ?
Merci pour vos avis !
Partager