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

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

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


相关文章
|
29天前
|
监控 安全 Java
异常类知识详解
异常类知识详解
|
6月前
|
缓存 安全 Java
从C语言到C++_35(异常)C++异常的使用+异常体系+异常优缺点(下)
从C语言到C++_35(异常)C++异常的使用+异常体系+异常优缺点
49 7
|
6月前
|
程序员 Linux C语言
从C语言到C++_35(异常)C++异常的使用+异常体系+异常优缺点(上)
从C语言到C++_35(异常)C++异常的使用+异常体系+异常优缺点
38 3
|
6月前
|
存储 Java API
掌握8条方法设计规则,设计优雅健壮的Java方法
掌握8条方法设计规则,设计优雅健壮的Java方法
|
6月前
|
Java
JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识
【5月更文挑战第2天】JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识。入坑JAVA因它的面向对象特性、平台无关性、强大的标准库和活跃的社区支持。
95 2
|
6月前
|
C++
C++语言异常处理学习应用案例
C++异常处理保证程序在运行时遇到错误(如除数为0)时不崩溃。以下是一个示例:程序接收用户输入的两个整数并进行除法运算。若除数为0,则抛出`std::runtime_error`异常。`try-catch`结构用来捕获并处理异常,当出现异常时,输出错误信息,使程序能继续执行。
49 4
|
6月前
|
缓存 Java 程序员
【C++】一文全解C++中的异常:标准库异常体系&自定义异常体系(含代码演示)
【C++】一文全解C++中的异常:标准库异常体系&自定义异常体系(含代码演示)
|
Java 编译器 程序员
Java异常处理和最佳实践(含案例分析)
读完本文应该了解Java异常处理机制,当一个异常被抛出时,JVM会在当前的方法里寻找一个匹配的处理,如果没有找到,这个方法会强制结束并弹出当前栈帧,并且异常会重新抛给上层调用的方法(在调用方法帧)。
956 5
Java异常处理和最佳实践(含案例分析)
|
存储 Java 编译器
Java异常是如何实现的?
Java异常是如何实现的?
Java异常是如何实现的?
|
测试技术
软件测试面试题:当一个接口出现异常时候,你是如何分析异常的?
软件测试面试题:当一个接口出现异常时候,你是如何分析异常的?
286 0