C++异常以及错误处理

c 语言中错误的处理, 通常采用返回值的方式或是置位全局变量的方式。 这就存在两个问题。
如果返回值正是我们需要的数据,且返回数据同出错数据容错差不高。全局变量,在多线程中易
引发竞争。而且,当错误发生时,上级函数要出错处理,层层上报,造成过多的出错处理代码,

且传递的效率低下。为此 c++提供了异常。

1)C++的异常处理机制使得异常的引发和异常的处理不必在同一个函数中,这样底层的函
数可以着重解决具体问题,而不必过多的考虑异常的处理。上层调用者可以再适当的位置设计对
不同类型异常的处理。
2)异常是专门针对抽象编程中的一系列错误处理的,C++中不能借助函数机制,因为栈结
构的本质是先进后出,依次访问,无法进行跳跃,但错误处理的特征却是遇到错误信息就想要转
到若干级之上进行重新尝试,

3)异常超脱于函数机制,决定了其对函数的跨越式回跳。异常跨越函数
分析:
1,把可能发生异常的语句放在 try 语句声当中。try 原有语句的执行流程。
2,若未发生异常,catch 子语句并不起作用。程序会流转到 catch 子句的后面执行。
3,若 try 块中发生异常,则通过 throw 抛出异常。throw 抛出异常后,程序立即离开
本函数,转到上一级函数。所以 triangle 函数中的 return 语句不会执行。
4,throw 抛出数据,类型不限。既可以是基本数据类型,也可以是构造数据类型。
5,程序流转到 main 函数以后,try 语句块中 抛出进行匹配。匹配成功,执行 catch 语
句,catch 语句执行完毕后。继续执行后面的语句。如无匹配,系统调用 terminate 终止
程序。

try
{
被检查的语句
}
catch(异常信息类型 [变量名])
{
进行异常处理的语句
}

1,被检语句必须放在 try 块中,否则不起作用。
2,try catch 中花括号不可省。
3,一个 try-catch 结构中,只能有一个 try 块,catch 块却可以有多个。以便与不同的类
型信息匹配。
try{}
catch(double){}
catch(int){}
catch(char){}
catch(float){}
4,throw 抛出的类型,既可以是系统预定义的标准类型也可以是自定义类型。从抛出到
catch 是一次复制拷贝的过程。如果有自定义类型,要考虑自定义类型的拷贝问题。
5.如果 catch 语句没有匹配异常类型信息,就可以用(...)表示可以捕获任何异常类型的信
息。
catch(...)
{
cout<<"catch a unknow exception"<<endl;
}

6.try-catch 结构可以与 throw 在同一个函中数中,也可以不在同一个函数中,throw 抛
出异常后,先在本函数内寻找与之匹配的 catch 块,找不到与之匹配的就转到上一层,如
果上一层也没有,则转到更上一层的 catch 块。如果最终找不到与之匹配的 catch 块,
系统则会调有生个系统函数,terminate,使程序终止

1)为了加强程序的可读性,可以在函数声明中列出可能抛出的所有异常类型。
例如:
void func() throw (A, B, C , D); //这个函数 func()能够且只能抛出类型 A B C D
及其子类型的异常。
2)如果在函数声明中没有包含异常接口声明,则函数可以抛掷任何类型的异常,例如:
void func();
3)一个不抛掷任何类型异常的函数可以声明为:
void func() throw();
4)如果一个函数抛出了它的异常接口声明所不允许抛出的异常, unexpected 函数会被 调
用,该函数默认行为调用 terminate 函数中止程序。

异常被抛出后,从进入 try 块起,到异常被抛掷前,这期间在栈上的构造的所有对象,都
会被自动析构。析构的顺序与构造的顺序相反。这一过程称为栈的解旋(unwinding)。
而堆上的空间,则会泄漏。

示例1



#include <iostream>
#include <string.h>
#include <unistd.h>


using namespace std;


void C()
{
throw 5;
}


void B()
{
C();
}


void A()
{
try {
B();
} catch (int i)
{
cout<<"catch exception "<<i<<endl;
}
}




int main(int argc, char **argv)
{
A();
return 0;
}


示例2



#include <iostream>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>


using namespace std;


void C(int i)
{
int a = 1;
double b= 1.2;
float c = 1.3;


if (i == 0)
{
cout<<"In C, it is OK"<<endl;
}
else if (i == 1)
throw a;
else if (i == 2)
throw b;
else 
throw c;
}


void B(int i)
{
cout<<"call C ..."<<endl;
C(i);
cout<<"After call C"<<endl;
}


void A(int i)
{
try {
B(i);
} catch (int j)
{
cout<<"catch exception "<<j<<endl;
}
}




int main(int argc, char **argv)
{
int i;
if (argc != 2)
{
cout<<"Usage: "<<endl;
cout<<argv[0]<<" <0|1|2|3>"<<endl;
return -1;
}


i = strtoul(argv[1], NULL, 0);


A(i);

return 0;
}




示例3



#include <iostream>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>


using namespace std;


void C(int i)
{
int a = 1;
double b= 1.2;
float c = 1.3;


if (i == 0)
{
cout<<"In C, it is OK"<<endl;
}
else if (i == 1)
throw a;
else if (i == 2)
throw b;
else 
throw c;
}


void B(int i)
{
cout<<"call C ..."<<endl;
C(i);
cout<<"After call C"<<endl;
}


void A(int i)
{
try {
B(i);
} catch (int j)
{
cout<<"catch int exception "<<j<<endl;
} catch (double d)
{
cout<<"catch double exception "<<d<<endl;
} catch (...){
cout<<"catch other exception "<<endl;
}
}




int main(int argc, char **argv)
{
int i;
if (argc != 2)
{
cout<<"Usage: "<<endl;
cout<<argv[0]<<" <0|1|2|3>"<<endl;
return -1;
}


i = strtoul(argv[1], NULL, 0);


A(i);

return 0;
}




示例4



#include <iostream>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>


using namespace std;


class MyException {
public:
void what(void) { cout<<"This is MyException"<<endl; }
};




void C(int i)
{
int a = 1;
double b= 1.2;
float c = 1.3;


if (i == 0)
{
cout<<"In C, it is OK"<<endl;
}
else if (i == 1)
throw a;
else if (i == 2)
throw b;
else if (i == 3)
throw c;
else if (i == 4)
throw MyException();
}


void B(int i)
{
cout<<"call C ..."<<endl;
C(i);
cout<<"After call C"<<endl;
}


void A(int i)
{
try {
B(i);
} catch (int j)
{
cout<<"catch int exception "<<j<<endl;
} catch (double d)
{
cout<<"catch double exception "<<d<<endl;
} catch (MyException &e)
{
e.what();
} catch (...){
cout<<"catch other exception "<<endl;
}
}




int main(int argc, char **argv)
{
int i;
if (argc != 2)
{
cout<<"Usage: "<<endl;
cout<<argv[0]<<" <0|1|2|3>"<<endl;
return -1;
}


i = strtoul(argv[1], NULL, 0);


A(i);

return 0;
}




示例5



#include <iostream>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>


using namespace std;


class MyException {
public:
void what(void) { cout<<"This is MyException"<<endl; }
};


class MySubException : public MyException{
public:
void what(void) { cout<<"This is MySubException"<<endl; }
};




void C(int i)
{
int a = 1;
double b= 1.2;
float c = 1.3;


if (i == 0)
{
cout<<"In C, it is OK"<<endl;
}
else if (i == 1)
throw a;
else if (i == 2)
throw b;
else if (i == 3)
throw c;
else if (i == 4)
throw MyException();
else if (i == 5)
throw MySubException();
}


void B(int i)
{
cout<<"call C ..."<<endl;
C(i);
cout<<"After call C"<<endl;
}


void A(int i)
{
try {
B(i);
} catch (int j)
{
cout<<"catch int exception "<<j<<endl;
} catch (double d)
{
cout<<"catch double exception "<<d<<endl;
} catch (MySubException &e)
{
e.what();
} catch (MyException &e)
{
e.what();
} catch (...){
cout<<"catch other exception "<<endl;
}
}




int main(int argc, char **argv)
{
int i;
if (argc != 2)
{
cout<<"Usage: "<<endl;
cout<<argv[0]<<" <0|1|2|3>"<<endl;
return -1;
}


i = strtoul(argv[1], NULL, 0);


A(i);

return 0;
}




示例6



#include <iostream>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>


using namespace std;


class MyException {
public:
virtual void what(void) { cout<<"This is MyException"<<endl; }
};


class MySubException : public MyException{
public:
void what(void) { cout<<"This is MySubException"<<endl; }
};




void C(int i)
{
int a = 1;
double b= 1.2;
float c = 1.3;


if (i == 0)
{
cout<<"In C, it is OK"<<endl;
}
else if (i == 1)
throw a;
else if (i == 2)
throw b;
else if (i == 3)
throw c;
else if (i == 4)
throw MyException();
else if (i == 5)
throw MySubException();
}


void B(int i)
{
cout<<"call C ..."<<endl;
C(i);
cout<<"After call C"<<endl;
}


void A(int i)
{
try {
B(i);
} catch (int j)
{
cout<<"catch int exception "<<j<<endl;
} catch (double d)
{
cout<<"catch double exception "<<d<<endl;
} catch (MyException &e)
{
e.what();
} catch (...){
cout<<"catch other exception "<<endl;
}
}




int main(int argc, char **argv)
{
int i;
if (argc != 2)
{
cout<<"Usage: "<<endl;
cout<<argv[0]<<" <0|1|2|3>"<<endl;
return -1;
}


i = strtoul(argv[1], NULL, 0);


A(i);

return 0;
}




示例7



#include <iostream>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>


using namespace std;


class MyException {
public:
virtual void what(void) { cout<<"This is MyException"<<endl; }
};


class MySubException : public MyException{
public:
void what(void) { cout<<"This is MySubException"<<endl; }
};




void C(int i) throw(int, double)
{
int a = 1;
double b= 1.2;
float c = 1.3;


if (i == 0)
{
cout<<"In C, it is OK"<<endl;
}
else if (i == 1)
throw a;
else if (i == 2)
throw b;
else if (i == 3)
throw c;
else if (i == 4)
throw MyException();
else if (i == 5)
throw MySubException();
}


void B(int i)
{
cout<<"call C ..."<<endl;
C(i);
cout<<"After call C"<<endl;
}


void A(int i)
{
try {
B(i);
} catch (int j)
{
cout<<"catch int exception "<<j<<endl;
} catch (double d)
{
cout<<"catch double exception "<<d<<endl;
} catch (MyException &e)
{
e.what();
} catch (...){
cout<<"catch other exception "<<endl;
}
}


void my_unexpected_func() 
{
cout<<"my_unexpected_func"<<endl;
}


void my_terminate_func () { cout<<"my_terminate_func"<<endl; }  




int main(int argc, char **argv)
{
int i;


set_unexpected (my_unexpected_func);
set_terminate(my_terminate_func);

if (argc != 2)
{
cout<<"Usage: "<<endl;
cout<<argv[0]<<" <0|1|2|3>"<<endl;
return -1;
}


i = strtoul(argv[1], NULL, 0);


A(i);

return 0;
}




示例8



#include <iostream>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>


using namespace std;


class MyException {
public:
virtual void what(void) { cout<<"This is MyException"<<endl; }
};


class MySubException : public MyException{
public:
void what(void) { cout<<"This is MySubException"<<endl; }
};




void C(int i) throw(int, double)
{
int a = 1;
double b= 1.2;
float c = 1.3;


if (i == 0)
{
cout<<"In C, it is OK"<<endl;
}
else if (i == 1)
throw a;
else if (i == 2)
throw b;
else if (i == 3)
throw c;
else if (i == 4)
throw MyException();
else if (i == 5)
throw MySubException();
}


void B(int i)
{
cout<<"call C ..."<<endl;
C(i);
cout<<"After call C"<<endl;
}


void A(int i)
{
try {
B(i);
} catch (int j)
{
cout<<"catch int exception "<<j<<endl;
} catch (MyException &e)
{
e.what();

}


void my_unexpected_func() 
{
cout<<"my_unexpected_func"<<endl;
}


void my_terminate_func () { cout<<"my_terminate_func"<<endl; }  




int main(int argc, char **argv)
{
int i;


set_unexpected (my_unexpected_func);
set_terminate(my_terminate_func);

if (argc != 2)
{
cout<<"Usage: "<<endl;
cout<<argv[0]<<" <0|1|2|3>"<<endl;
return -1;
}


i = strtoul(argv[1], NULL, 0);


A(i);

return 0;
}












  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值