A good way to learn programs is to read the code and improve the code.
The following example is from An Overview of the C ++ Programming Language (5.1 exception and error handling)
Program purpose: Use the exception mechanism of c ++ to report the overflow or underflow of the stack. (I can complete the code properly .)
Version 1 demonstrates basic abnormal usage.
An exception (instance or object) is thrown from try, which is accepted by the class in catch.
1 version 1
2 // From: An Overview of the C ++ Programming Language
3
4 # include <cstdlib>
5 # include <iostream>
6 # include <string>
7 using namespace std;
8
9 template <class T> class Stack {
10 TB * v;
11 int max_size;
12 int top;
13 public:
14 class Underflow {}; // Underflow
15 class Overflow {}; // Overflow
16 // construct function. determine the size
17 Stack (int s): max_size (s), top (0) {v = new T [max_size];}
18 ~ Stack (){}
19 void push (T c ){
20 if (top = max_size) throw Overflow ();
21 v [top ++] = c;
22}
23 T pop (){
24 if (top = 0) throw Underflow ();
25 return v [-- top];
26}
27 };
28
29 void f ()
30 {
31 Stack <string> ss (10 );
32 try {
33 ss. push ("Quiz ");
34 string s = ss. pop ();
35 ss. pop ();
36}
37 catch (Stack <string >:: Overflow ){
38 cerr <"error: stack overflow" <endl;
39}
40 catch (Stack <string >:: Underflow ){
41 cerr <"error: stack underflow" <endl;
42}
43}
44
45 int main (int argc, char * argv [])
46 {
47 f ();
48 system ("PAUSE ");
49 return EXIT_SUCCESS;
50}
51
52. output result: error: stack underflow
53
54
Improvement: our second version is as follows:
If
1 class Underflow {}; // Underflow
2 class Overflow {}; // Overflow
3 and
4 catch (Stack <string >:: Overflow ){
5 cerr <"error: stack overflow" <endl;
6}
7 catch (Stack <string >:: Underflow ){
8 cerr <"error: stack underflow" <endl;
9}
10
Change to the following:
1
2 class Underflow {//
3 public:
4 void error (void ){
5 cerr <"stack Underflow" <endl;
6}
7 };
8 class Overflow {//
9 public:
10 void error (void ){
11 cerr <"stack Overflow" <endl;
12}
13 };
14 and
15 catch (Stack <string >:: Overflow & e ){
16 e. error ();
17}
18 catch (Stack <string >:: Underflow & e ){
19 e. error ();
20}
21
What is the difference between the modified program and the original one? Heheh.
Of course, we can also improve the code. This produces the third version.
Version 3: version3
Add a class Stack_error to the Stack so that both Underflow and Overflow can inherit it:
1 template <class T> class Stack {
2 //
3 public:
4 class stack_error {
5 public:
6 virtual void error (void) {// Of course, you can make it virtual. Abstract class.
7 cerr <"stack_error" <endl;
8}
9 };
10 class Underflow: public stack_error {//
11 public:
12 void error (void ){
13 cerr <"stack Underflow" <endl;
14}
15 };
16 class Overflow: public stack_error {//
17 public:
18 void error (void ){
19 cerr <"stack Overflow" <endl;
20}
21 };
22 //
23}
24
Then combine the two catch into a catch, as shown below.
Try {
// The same
}
Catch (Stack <string >:: stack_error & e ){
E. error ();
}
The functions of these three versions are the same, but the higher the version, the clearer the code, and the easier the code maintenance.
If we have designed a library (such as the Stack above), we will first think of two exceptions: overflow and underflow. If you have two methods to design a Stack: version1 and version3, the function f () (User Code) is also version1 and version3. When a period of time has passed, we are going to add another exception, such as midflow () (hehahaha, I cannot think of any similar exception ). In this case, the library designer said to the user, "we have found a midflow () exception and added it to the Code for receiving the data. Please rewrite your code f ()."
In this way, we need to modify version1 to the following format:
Void f ()
{
Stack <string> ss (10 );
Try {
//.
}
Catch (Stack <string >:: Overflow ){
Cerr <"error: stack overflow" <endl;
}
Catch (Stack <string >:: Underflow ){
Cerr <"error: stack underflow" <endl;
}
Catch (Stack <string >:: Midflow) {// we found all the code that caught stack exceptions and added these two sentences.
Cerr <"error: stack midflow" <endl;
}
}
Version3 inherits stack_error because of midflow. The interface is the same, and the customer Code does not need to be changed.
Appendix: version3 complete code:
1 Version 3:
2 # include <cstdlib>
3 # include <iostream>
4
5 using namespace std;
6
7 template <class T> class Stack {
8 T * v;
9 int max_size;
10 int top;
11 public:
12 class stack_error {
13 public:
14 virtual void error (void) = 0;
15 };
16
17 class Underflow: public stack_error {//
18 public:
19 void error (void ){
20 cerr <"stack Underflow" <endl;
21}
22 };
23 class Overflow: public stack_error {//
24 public:
25 void error (void ){
26 cerr <"stack Overflow" <endl;
27}
28 };
29 Stack (int s): max_size (s), top (0) {v = new T [max_size];} // construct function. determine the size
30 ~ Stack (){}
31 void push (T c ){
32 if (top = max_size) throw Overflow ();
33 v [top ++] = c;
34}
35 T pop (){
36 if (top = 0) throw Underflow ();
37 return v [-- top];
38}
39 };
40
41 void f ()
42 {
43 Stack <string> ss (0 );
44 try {
45 ss. push ("Quiz ");
46 string s = ss. pop ();
47 ss. pop ();
48}
49 catch (Stack <string >:: stack_error & e ){
50 e. error ();
51}
52
53}
54
55 int main (int argc, char * argv [])
56 {
57 f ();
58 system ("PAUSE ");
59 return EXIT_SUCCESS;
60}