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

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

构造函数和析构函数没有返回值,不能像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");


相关文章
|
23天前
|
Java 程序员
Java编程中的异常处理:从基础到高级
在Java的世界中,异常处理是代码健壮性的守护神。本文将带你从异常的基本概念出发,逐步深入到高级用法,探索如何优雅地处理程序中的错误和异常情况。通过实际案例,我们将一起学习如何编写更可靠、更易于维护的Java代码。准备好了吗?让我们一起踏上这段旅程,解锁Java异常处理的秘密!
|
5月前
|
设计模式 安全 Java
Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
129 0
|
7月前
|
缓存 安全 Java
从C语言到C++_35(异常)C++异常的使用+异常体系+异常优缺点(下)
从C语言到C++_35(异常)C++异常的使用+异常体系+异常优缺点
61 7
|
7月前
|
程序员 Linux C语言
从C语言到C++_35(异常)C++异常的使用+异常体系+异常优缺点(上)
从C语言到C++_35(异常)C++异常的使用+异常体系+异常优缺点
47 3
|
7月前
|
存储 Java API
掌握8条方法设计规则,设计优雅健壮的Java方法
掌握8条方法设计规则,设计优雅健壮的Java方法
|
7月前
|
Java
JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识
【5月更文挑战第2天】JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识。入坑JAVA因它的面向对象特性、平台无关性、强大的标准库和活跃的社区支持。
106 2
|
7月前
|
设计模式 安全 编译器
【C++ 异常】C++异常处理:掌握高效、健壮代码的秘密武器
【C++ 异常】C++异常处理:掌握高效、健壮代码的秘密武器
139 1
|
7月前
|
算法 程序员 编译器
【C++ 异常】深入探究C++的stdexcept类库
【C++ 异常】深入探究C++的stdexcept类库
77 0
|
7月前
|
缓存 Java 程序员
【C++】一文全解C++中的异常:标准库异常体系&自定义异常体系(含代码演示)
【C++】一文全解C++中的异常:标准库异常体系&自定义异常体系(含代码演示)
|
Java Spring
案例07 OOP方式实现日志记录案例
采用OOP的面向对象编程方式,对学生信息管理系统中的新增学生信息、更新学生信息和删除学生信息3个方法实现日志记录业务。
72 0

热门文章

最新文章