【异常机制高级讲解】异常与多态综合案例

简介: 【异常机制高级讲解】异常与多态综合案例

构造函数和析构函数没有返回值,不能像C语言那样用不同的返回值来判断错误的情概况,所以可以通过异常机制来处理错误的情况。

下面给出一个综合案例,该案例包含了异常、多态、类内部包含类、深拷贝、操作符重载、虚函数重写、等综合性知识。(该综合案例将C++的很多语法结合在一起,综合性较强,值得反复练习调试

1. #define _CRT_SECURE_NO_WARNINGS
2. 
3. #include <iostream>
4. using namespace std;
5. 
6. class People
7. {
8. public: //构造析构函数
9.  People(int age, const char* name);
10.   ~People();
11. public: //重载操作符
12.   char& operator[](int index);
13.   friend ostream& operator<<(ostream& out, People& p);
14. public: //提供外部访问私有属性的接口
15.   int get_age();
16. public: //内部类定义异常类型,实现捕获异常的多态行为
17.   class PeopleErrType
18.   {
19.   public:
20.     PeopleErrType(const char* p);
21.     ~PeopleErrType();
22.   public:
23.     virtual void print_err_type() = 0; //People 类中异常的统一接口
24.   protected:
25.     char* err_type_str;
26.   };
27.   class PeopleAgeTooSmall : public PeopleErrType
28.   {
29.   public:
30.     PeopleAgeTooSmall(const char* p) : PeopleErrType(p) {}; //只用于初始化参数列表传给父类
31.   public:
32.     virtual void print_err_type();
33.   };
34.   class PeopleAgeTooBig : public PeopleErrType
35.   {
36.   public:
37.     PeopleAgeTooBig(const char* p) : PeopleErrType(p) {};
38.   public:
39.     virtual void print_err_type();
40.   };
41.   class PeopleNameIsNULL : public PeopleErrType
42.   {
43.   public:
44.     PeopleNameIsNULL(const char* p) : PeopleErrType(p) {};
45.   public:
46.     virtual void print_err_type();
47.   };
48.   class PeopleNameErr : public PeopleErrType
49.   {
50.   public:
51.     PeopleNameErr(const char* p) : PeopleErrType(p) {};
52.   public:
53.     virtual void print_err_type();
54.   };
55. private: //私有属性
56.   int age; //年龄
57.   char* name; //名称
58. };
59. 
60. // People 类的构造函数,会抛出异常
61. People::People(int age, const char* name)
62. {
63.   if (age <= 0)
64.   {
65.     throw PeopleAgeTooSmall("异常:年龄小于0");
66.   }
67.   if (age > 200)
68.   {
69.     throw PeopleAgeTooBig("异常:年龄大于200");
70.   }
71.   if (name == NULL)
72.   {
73.     throw PeopleNameIsNULL("异常:名称为空");
74.   }
75.   if ((name[0] < 'A') || (name[0] > 'Z'))
76.   {
77.     throw PeopleNameErr("异常:名称错误,(name[0] < 'A') || (name[0] > 'Z')");
78.   }
79. 
80.   this->age = age;
81.   this->name = new char[strlen(name) + 1];
82.   strcpy(this->name, name);
83. }
84. 
85. // People 类的析构函数
86. People::~People()
87. {
88.   if (this->name != NULL)
89.   {
90.     delete[] this->name;
91.   }
92.   this->name = NULL;
93.   this->age = 0;
94. }
95. 
96. //外部访问私有属性的接口
97. int People::get_age()
98. {
99.   return this->age;
100. }
101. 
102. //重载 [] 操作符
103. char& People::operator[](int index)
104. {
105.  return this->name[index];
106. }
107. 
108. //重载左移操作符
109. ostream& operator<<(ostream& out, People& p)
110. {
111.  out << "name: " << p.name << " age: " << p.age << endl;
112.  return out;
113. }
114. 
115. //People 类的内部类 构造函数,为输出字符串分配空间
116. People::PeopleErrType::PeopleErrType(const char* p)
117. {
118.  this->err_type_str = new char[strlen(p) + 1];
119.  strcpy(this->err_type_str, p);
120. }
121. 
122. People::PeopleErrType::~PeopleErrType()
123. {
124.  if (this->err_type_str != NULL)
125.  {
126.    delete[] this->err_type_str;
127.  }
128.  this->err_type_str = NULL;
129. }
130. 
131. //异常类型:年龄太小,小于0
132. void People::PeopleAgeTooSmall::print_err_type()
133. {
134.  cout << "err: PeopleAgeTooSmall -> " << err_type_str << endl;
135. }
136. 
137. //异常类型:年龄太大超出范围
138. void People::PeopleAgeTooBig::print_err_type()
139. {
140.  cout << "err: PeopleAgeTooBig -> " << err_type_str << endl;
141. }
142. 
143. //异常类型:名称为空
144. void People::PeopleNameIsNULL::print_err_type()
145. {
146.  cout << "err: PeopleNameIsNULL -> " << err_type_str << endl;
147. }
148. 
149. //异常类型:名称错误
150. void People::PeopleNameErr::print_err_type()
151. {
152.  cout << "err: PeopleNameErr -> " << err_type_str << endl;
153. }
154. 
155. int main()
156. {
157.  try
158.  {
159. //通过以下4个测试例子测试4种异常
160.    //People p(0, "Aily");
161.    //People p(16, NULL);
162.    //People p(300, "Aily");
163.    //People p(16, "aily");
164.    People p(16, "Aily");
165.    cout << "人员信息:" << p << "\t代号:" << p[0] << p.get_age() << endl;
166.  }
167.  catch (People::PeopleErrType & e) //产生多态,自动识别异常类型
168.  {
169.    e.print_err_type();
170.  }
171.  catch (...)
172.  {
173.    cout << "其他未知异常" << endl;
174.  }
175. 
176.  system("pause");
177.  return 0;
178. }

将测试代码依次放开,逐步调试便可以观察到程序的每一步动态

1. //通过以下4个测试例子测试4种异常
2. //People p(0, "Aily");
3. //People p(16, NULL);
4. //People p(300, "Aily");
5. //People p(16, "aily");
6. //People p(16, "Aily");


相关文章
|
11月前
|
Java
CompletableFuture在异常处理方面的一些常见问题和解决方案,建议牢记!
CompletableFuture在异常处理方面的一些常见问题和解决方案,建议牢记!
343 0
CompletableFuture在异常处理方面的一些常见问题和解决方案,建议牢记!
|
3月前
|
Java UED 开发者
【技术解密】Java异常处理新玩法:throw关键字,你的错误管理利器!
【6月更文挑战第19天】Java异常处理关键在于`throw`,它用于主动抛出异常,确保程序健壮性。例如,当年龄验证失败时,`IllegalArgumentException`被`throw`,提供错误详情。自定义异常如`CustomException`能增强错误信息。此外,通过构建异常链,如在`DataProcessingException`中嵌套`IOException`,保持原始堆栈信息,提供更全面的错误上下文。掌握`throw`能提升错误管理,打造稳定软件。
38 5
|
4月前
|
缓存 安全 Java
从C语言到C++_35(异常)C++异常的使用+异常体系+异常优缺点(下)
从C语言到C++_35(异常)C++异常的使用+异常体系+异常优缺点
38 7
|
4月前
|
程序员 Linux C语言
从C语言到C++_35(异常)C++异常的使用+异常体系+异常优缺点(上)
从C语言到C++_35(异常)C++异常的使用+异常体系+异常优缺点
31 3
|
3月前
|
C++
C++对C的改进和拓展\异常处理
C++对C的改进和拓展\异常处理
23 0
|
4月前
|
存储 Java API
掌握8条方法设计规则,设计优雅健壮的Java方法
掌握8条方法设计规则,设计优雅健壮的Java方法
|
4月前
|
设计模式 安全 编译器
【C++ 异常】C++异常处理:掌握高效、健壮代码的秘密武器
【C++ 异常】C++异常处理:掌握高效、健壮代码的秘密武器
94 1
|
4月前
|
缓存 Java 程序员
【C++】一文全解C++中的异常:标准库异常体系&自定义异常体系(含代码演示)
【C++】一文全解C++中的异常:标准库异常体系&自定义异常体系(含代码演示)
|
Java 编译器 程序员
Java异常处理和最佳实践(含案例分析)
读完本文应该了解Java异常处理机制,当一个异常被抛出时,JVM会在当前的方法里寻找一个匹配的处理,如果没有找到,这个方法会强制结束并弹出当前栈帧,并且异常会重新抛给上层调用的方法(在调用方法帧)。
879 6
Java异常处理和最佳实践(含案例分析)
|
存储 Java 编译器
Java异常是如何实现的?
Java异常是如何实现的?
Java异常是如何实现的?