C++-Programmierung/ Eine Matrix-Bibliothek – mitrax/ Klassen für die Ausnahmebehandlung
Die Fehlerklassen stehen in der Datei exception.hpp
. mitrax stellt einen eigenen Namensbereich namens error
für seine Fehlerklassen bereit. Die Fehler teilen sich in logische Fehler (von std::logic_error
abgeleitet) und Bereichsfehler (von std::out_of_range
abgeleitet) auf. Wenn eine mitrax-Funktion einen Fehler wirft, dann übergibt sie einen Text, anhand dessen sie identifiziert werden kann und, sofern vorhanden, die wesentlichen Informationen, die zu der Ausnahme geführt haben. Die Fehlerklassen generieren daraus jeweils einen passenden Standardtext. Da der generierte Text an den Basisklassenkonstruktor hoch gereicht wird, muss die Generierung nötigenfalls von einer privaten statischen Funktion ausgeführt werden. Viel mehr gibt es zu den Fehlerklassen eigentlich nicht zu sagen. Sie sehen wie Folgt aus.
1 class access: public std::out_of_range{
2 public:
3 explicit access(std::string const& what):std::out_of_range(what){}
4 explicit access(char const* what):std::out_of_range(what){}
5 };
6
7
8 class row_access: public access{
9 public:
10 template < typename SizeType >
11 row_access(
12 std::string const& text,
13 mitrax::dimension< SizeType > const& size,
14 SizeType const& row_number
15 ):
16 access(make_text(text, size, row_number))
17 {}
18
19 private:
20 template < typename SizeType >
21 static std::string const make_text(
22 std::string const& text,
23 mitrax::dimension< SizeType > const& size,
24 SizeType const& row_number
25 ){
26 std::ostringstream error;
27 error << text << ": Dimension(" << size.rows() << ", " << size.columns()
28 << "): access in row " << row_number << " not allowed";
29 return error.str();
30 }
31 };
32
33
34 class column_access: public access{
35 public:
36 template < typename SizeType >
37 column_access(
38 std::string const& text,
39 mitrax::dimension< SizeType > const& size,
40 SizeType const& column_number
41 ):
42 access(make_text(text, size, column_number))
43 {}
44
45 private:
46 template < typename SizeType >
47 static std::string const make_text(
48 std::string const& text,
49 mitrax::dimension< SizeType > const& size,
50 SizeType const& column_number
51 ){
52 std::ostringstream error;
53 error << text << ": Dimension(" << size.rows() << ", " << size.columns()
54 << "): access in column " << column_number << " not allowed";
55 return error.str();
56 }
57 };
58
59
60 class data_size: public std::logic_error{
61 public:
62 template < typename SizeType, typename Container >
63 data_size(std::string const& text, dimension< SizeType > const& size, Container const& data):
64 std::logic_error(make_text(text, size, data))
65 {}
66
67 private:
68 template < typename SizeType, typename Container >
69 static std::string const make_text(
70 std::string const& text, mitrax::dimension< SizeType > const& size, Container const& data
71 ){
72 std::ostringstream error;
73 error << text << ": Dimension(" << size.rows() << ", " << size.columns()
74 << ") not compatible with data-size " << data.size();
75 return error.str();
76 }
77 };
78
79
80 class dimension: public std::logic_error{
81 public:
82 explicit dimension(std::string const& what):std::logic_error(what){}
83 explicit dimension(char const* what):std::logic_error(what){}
84 };
85
86
87 class dimension_unequal: public dimension{
88 public:
89 template < typename SizeType >
90 dimension_unequal(
91 std::string const& text,
92 mitrax::dimension< SizeType > const& lhs,
93 mitrax::dimension< SizeType > const& rhs
94 ):
95 dimension(make_text(text, lhs, rhs)){}
96
97 private:
98 template < typename SizeType >
99 static std::string const make_text(
100 std::string const& text,
101 mitrax::dimension< SizeType > const& lhs,
102 mitrax::dimension< SizeType > const& rhs
103 ){
104 std::ostringstream error;
105 error << text << ": lhs.dimension(" << lhs.rows() << ", " << lhs.columns()
106 << ") != rhs.dimension(" << rhs.rows() << ", " << rhs.columns() << ")";
107 return error.str();
108 }
109 };
110
111
112 class dimension_incompatible: public dimension{
113 public:
114 template < typename SizeType >
115 dimension_incompatible(
116 std::string const& text,
117 mitrax::dimension< SizeType > const& lhs,
118 mitrax::dimension< SizeType > const& rhs
119 ):
120 dimension(make_text(text, lhs, rhs)){}
121
122 private:
123 template < typename SizeType >
124 static std::string const make_text(
125 std::string const& text,
126 mitrax::dimension< SizeType > const& lhs,
127 mitrax::dimension< SizeType > const& rhs
128 ){
129 std::ostringstream error;
130 error << text << ": lhs.dimension(" << lhs.rows() << ", " << lhs.columns()
131 << "), rhs.dimension(" << rhs.rows() << ", " << rhs.columns() << ")";
132 return error.str();
133 }
134 };
135
136
137 class not_quadratic: public dimension{
138 public:
139 template < typename SizeType >
140 not_quadratic(std::string const& text, mitrax::dimension< SizeType > const& dim):
141 dimension(make_text(text, dim)){}
142
143 private:
144 template < typename SizeType >
145 static std::string const make_text(
146 std::string const& text, mitrax::dimension< SizeType > const& dim
147 ){
148 std::ostringstream error;
149 error << text << ": dimension(" << dim.rows() << ", " << dim.columns() << ")";
150 return error.str();
151 }
152 };
153
154
155 class singular_matrix: public std::logic_error{
156 public:
157 explicit singular_matrix(std::string const& what):std::logic_error(what){}
158 explicit singular_matrix(char const* what):std::logic_error(what){}
159 };
160
161
162 class size_unequal: public std::logic_error{
163 public:
164 template < typename SizeType >
165 size_unequal(std::string const& text, SizeType const& lhs, SizeType const& rhs):
166 std::logic_error(make_text(text, lhs, rhs)){}
167
168 private:
169 template < typename SizeType >
170 static std::string const make_text(
171 std::string const& text, SizeType const& lhs, SizeType const& rhs
172 ){
173 std::ostringstream error;
174 error << text << ": " << lhs << " != " << rhs;
175 return error.str();
176 }
177 };
Somit sind Ihnen alle Fehler bekannt, die von mitrax geworfen werden können. Einige der Stelle, an denen dies geschielt haben Sie in den letzten Kapiteln schon kennen gelernt, die meisten Ausnahmen werden jedoch bei Berechnungen geworfen. Wenn Sie also als Benutzer neue Berechnungen einführen, dann ist es nicht unwahrscheinlich, dass Sie auch weitere Fehlerklassen hinzufügen müssen. Sofern diese eine Verwandtschaft mit einer der hier bereits existierenden Klassen aufweisten ist es natürlich sinnvoll, von dieser abzuleiten.