异常在编程中是一个非常重要的概念,它指的是程序在执行过程中出现的非正常的情况。异常可能导致程序无法正常运行或产生错误的结果。
在许多编程语言中,异常是一个对象,它包含了关于异常的详细信息,例如异常类型、异常消息和异常堆栈跟踪。当程序中出现异常时,会创建一个相应的异常对象,并将该对象传递给处理程序。处理程序可以是程序中指定的异常处理器,也可以是默认的异常处理程序。
异常处理程序会根据异常的类型和消息,采取适当的行动来处理异常。它可以记录异常信息、恢复程序的执行或采取其他措施来解决问题。在某些情况下,异常处理程序还可以修改程序的行为或返回值,以避免程序崩溃或提供有关错误的信息。
异常处理是编程中一个重要的部分,它可以帮助开发人员更好地控制程序的执行流程,提高程序的稳定性和可靠性。通过使用异常处理机制,开发人员可以及时发现和修复错误,避免程序崩溃或产生不正确的结果。
- 异常
11.1.引例
#include <iostream>
using namespace std;
int divide(int x, int y)
{
if(y == 0)
throw('a');
return x/y;
}
int myDivide(int x, int y)
{
divide(x,y) ;
}
int main()
{
try{
myDivide(4,0);
}catch(int x){
cout<<"x"<<endl;
cout<<x<<endl;
}catch(double y){
cout<<"y"<<endl;
cout<<y<<endl;
}catch(...){
cout<<"no x, no y"<<endl;
}
return 0;
}
小结:
1,函数定义在有可能发生错误的地方,设立异常抛出。可以抛出任意类型(包括内嵌类型或自定义类型)。
2,try-catch 结构,try 结构包含可能发生异常的函数。catch 模块是异常发生时走的分支,跟抛出类型进行严格匹配。可以有多个 catch 块。
try
{ 被检查的语句}
catch(异常信息类型 [变量名])
{ 进行异常处理的语句}
3. 异常的抛出,可以跨函数。省却函数层层返回,这也是他的优势。
4,catch(…)作为抛出类型不匹配的分支。
5,如无匹配的分支,系统由会调用 terminate,使其终止,并提示信息。
11.2.引入模板的意义
1)C++的异常处理机制使得异常的引发和异常的处理不必在同一个函数中,这样底层的函数可以着重解决具体问题,而不必过多的考虑异常的处理。上层调用者可以再适当的位置设计对不同类型异常的处理。
2)异常是专门针对抽象编程中的一系列错误处理的,C++中不能借助函数机制,因为栈结构的本质是先进后出,依次访问,无法进行跳跃,但错误处理的特征却是遇到错误信息就想要转到若干级之上进行重新尝试,如图
3)异常超脱于函数机制,决定了其对函数的跨越式回跳。
4)异常跨越函数
11.3.引入异常需要解决的问题
11.3.1. 抛出类型声明
1)为了加强程序的可读性,可以在函数声明中列出可能抛出的所有异常类型。
例如:
void func() throw (A, B, C , D); //这个函数 func()能够且只能抛出类型 A B C D 及其子
类型的异常。
2)如果在函数声明中没有包含异常接口声明,则次函数可以抛掷任何类型的异常,例如:
void func();
3)一个不抛掷任何类型异常的函数可以声明为:
void func() throw();
4)如果一个函数抛出了它的异常接口声明所不允许抛出的异常,unexpected 函数会被调用,该函数默认行为调用 terminate 函数中止程序。
11.3.2. 栈自旋
异常被抛出后,从进入 try 块起,到异常被抛掷前,这期间在栈上的构造的所有对象,都会被自动析构。析构的顺序与构造的顺序相反。这一过程称为栈的解旋(unwinding)。而堆上的空间,则会泄漏。
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout<<"A constructor"<<endl;
}
~A()
{
cout<<"~A destructor"<<endl;
}
};
int divide(int x, int y)
{
A a;
if(y == 0)
throw('a');
return x/y;
}
int myDivide(int x, int y)
{
A b;
divide(x,y) ;
}
int main()
{
try{
myDivide(4,0);
}catch(int x){
cout<<"x"<<endl;
cout<<x<<endl;
}catch(double y){
cout<<"y"<<endl;
cout<<y<<endl;
}catch(...){
cout<<"no x, no y"<<endl;
}
return 0;
}
11.3.3. 返回类对象(引用,实例)
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout<<"A constructor"<<endl;
}
A(const A & )
{
cout<<"A copy constructor"<<endl;
}
~A()
{
cout<<"~A destructor"<<endl;
}
};
int divide(int x, int y)
{
A a;
if(y == 0)
throw(a);
return x/y;
}
int myDivide(int x, int y)
{
divide(x,y) ;
}
int main()
{
try{
myDivide(4,0);
}catch(int x){
cout<<"x"<<endl;
cout<<x<<endl;
}catch(double y){
cout<<"y"<<endl;
cout<<y<<endl;
}catch(const A &a){
cout<<"no x, no y"<<endl;
}
return 0;
}
12. STL
13. C11
14. Boost
15. 附录
15.1.运算符优先级
15.2.ASCII 码
C++编程宝典:快速上手、深入进阶、挑战高级技巧,助你成为编程达人教程至此全部结束!有需要的可以到本站下载PDF版本感谢支持