#include <cstdlib>
#include <iostream>
using namespace std;
int MemSet(void* dest, unsigned int length, unsigned char v)
{
if( dest == NULL )
{
return -1;
}
if( length < 4 )
{
return -2;
}
if( (v < 0) || (v > 9) )
{
return -3;
}
unsigned char* p = (unsigned char*)dest;
for(int i=0; i<length; i++)
{
p[i] = v;
}
return 0;
}
int main(int argc, char *argv[])
{
int ai[5];
double ad[4];
char ac[3];
int ret;
ret = MemSet(ai, sizeof(ai), 0);
if( ret == 0 )
{
}
else if( ret == -1 )
{
}
else if( ret == -2 )
{
}
else if( ret == -3 )
{
}
ret = MemSet(ad, sizeof(ad), 1);
if( ret == 0 )
{
}
else if( ret == -1 )
{
}
else if( ret == -2 )
{
}
else if( ret == -3 )
{
}
ret = MemSet(ac, sizeof(ac), 2);
if( ret == 0 )
{
}
else if( ret == -1 )
{
}
else if( ret == -2 )
{
}
else if( ret == -3 )
{
}
cout << "Press the enter key to continue ...";
cin.get();
return EXIT_SUCCESS;
} c.可见条件判断的方法,使得正常逻辑的代码和异常处理的代码混合在一起,导致代码迅速膨胀,难以维护!而goto语句和setjmp()、longjmp()函数则可以将异常处理代码放在统一的地方,与正常逻辑代码分开。#include <iostream>
#define div_zero_error 1
using namespace std;
double div(double a, double b)
{
if((-0.0000001<b)&&(b<0.0000001))
{
throw div_zero_error;
}
return a/b;
}
int main()
{
char a = ‘c‘; //try语句块外面依然可以放其他语句
try
{
cout << div(2,3) << endl;
throw a; //throw后面可以直接 放数据 也可以放变量
//throw ‘d‘;
cout << div(1,0) << endl;
cout << div(5,2) << endl;
}
catch(int a)
{
cout << "div_zero_error" << endl;
}
catch(char) //catch语句后面,可以只有变量类型,没有具体变量
{
cout << "test_error" << endl;
}
return 0;
}
注意:第一,并不是所有语句都要全部放在try或者catch语句块里面,可以放在try或者catch语句外面!#include <cstdlib>
#include <iostream>
using namespace std;
void MemSet(void* dest, unsigned int length, unsigned char v)
{
if( dest == NULL )
{
throw -1;
}
if( length < 4 )
{
throw -2;
}
if( (v < 0) || (v > 9) )
{
throw -3;
}
unsigned char* p = (unsigned char*)dest;
for(int i=0; i<length; i++)
{
p[i] = v;
}
}
int main(int argc, char *argv[])
{
int ai[5];
double ad[4];
char ac[3];
try
{
MemSet(ai, sizeof(ai), 0);
MemSet(ad, sizeof(ad), 1);
MemSet(ac, sizeof(ac), 2);
}
catch(int e)
{
cout<<e<<endl;
}
cout << "Press the enter key to continue ...";
cin.get();
return EXIT_SUCCESS;
}
注意:上面代码是c++异常处理的常规用法!#include <cstdlib>
#include <iostream>
using namespace std;
int MemSet(void* dest, unsigned int length, unsigned char v)
{
int ret = 0;
if( dest == NULL )
{
return -1;
}
if( length < 4 )
{
return -2;
}
if( (v < 0) || (v > 9) )
{
return -3;
}
unsigned char* p = (unsigned char*)dest;
for(int i=0; i<length; i++)
{
p[i] = v;
}
return 0;
}
int main(int argc, char *argv[])
{
int ai[5];
double ad[4];
char ac[3];
if(0==MemSet(ai, sizeof(ai), 0))
{}
else
{
if(-1==MemSet(ai, sizeof(ai), 0))
{
cout << -1 << endl;
}
else if(-2==MemSet(ai, sizeof(ai), 0))
{
cout << -2 << endl;
}
else if(-3==MemSet(ai, sizeof(ai), 0))
{
cout << -3 << endl;
}
}
if(0==MemSet(ad, sizeof(ad), 1))
{}
else
{
if(-1==MemSet(ad, sizeof(ad), 1))
{
cout << -1 << endl;
}
else if(-2==MemSet(ad, sizeof(ad), 1))
{
cout << -2 << endl;
}
else if(-3==MemSet(ad, sizeof(ad), 1))
{
cout << -3 << endl;
}
}
if(0==MemSet(ac, sizeof(ac), 2))
{}
else
{
if(-1==MemSet(ac, sizeof(ac), 2))
{
cout << -1 << endl;
}
else if(-2==MemSet(ac, sizeof(ac), 2))
{
cout << -2 << endl;
}
else if(-3==MemSet(ac, sizeof(ac), 2))
{
cout << -3 << endl;
}
}
cout << "Press the enter key to continue ...";
cin.get();
return EXIT_SUCCESS;
}
注意:上面就是使用条件判断的异常处理方式,可见代码膨胀的样子!但是使用条件判断可以保证每一个正常逻辑的代码都得到执行,而try.....catch语句就保证不了!因为当发生throw异常的时候,代码就会跳转到catch语句块中,然后从catch语句块往后执行了!会丢失throw语句后面部分的正常逻辑代码!#include <cstdlib>
#include <iostream>
using namespace std;
int test(int i)
{
if( i == 1 )
{
throw -1;
}
if( i == 2 )
{
throw "ERROR";
}
if( i == 3 )
{
throw 0.5;
}
if( i == 4 )
{
throw ‘d‘;
}
return i;
}
int main(int argc, char *argv[])
{
for(int i=0; i<4; i++)
{
try
{
cout<<test(i)<<endl;
}
catch(int e)
{
cout<<"Int: "<<e<<endl;
}
catch(const char* e)
{
cout<<"const char*: "<<e<<endl;
}
catch(double e)
{
cout<<"double: "<<e<<endl;
}
}
cout << "Press the enter key to continue ...";
cin.get();
return EXIT_SUCCESS;
}注意:第一,catch后面可以只有类型,没有具体变量,但是当没有变量的时候,catch语句块中就不能获得throw语句抛出的异常参数了!#include <cstdlib>
#include <iostream>
using namespace std;
int test(int i)
{
if( i == 1 )
{
throw -1;
}
if( i == 2 )
{
throw "ERROR";
}
if( i == 3 )
{
throw 0.5;
}
if( i == 4 )
{
throw ‘d‘;
}
return i;
}
int main(int argc, char *argv[])
{
for(int i=0; i<5; i++)
{
try
{
try
{
cout<<test(i)<<endl;
}
catch(int)
{
// cout<<"Int: "<<e<<endl;
throw;
}
catch(const char* e)
{
cout<<"const char*: "<<e<<endl;
throw 3;
}
catch(double e)
{
cout<<"double: "<<e<<endl;
throw;
}
catch(...)
{
cout << "catch(...) " << endl;
throw;
}
}
catch(double a)
{
cout << "throw catch(double) " << endl;
}
catch(int a)
{
cout << "throw catch(int) " << endl;
cout << a << endl;
}
catch(char a)
{
cout << "throw catch(char) " << endl;
}
catch(...)
{
cout << "throw catch(...) " << endl;
}
}
cout << "Press the enter key to continue ...";
cin.get();
return EXIT_SUCCESS;
}
#include <iostream>
using namespace std;
class test
{
public:
test()
{
cout << "test()....." << endl;
throw ‘a‘;
}
~test()
{
cout << "~test()....." << endl;
}
};
void fun()
{
try
{
test t1;
}
catch(char e)
{
cout << e << endl;
}
}
int main()
{
fun();
return 0;
}
注意:上面的对象因为是构造不完全的对象,所以对象的析构函数不被调用!#include <iostream>
#include <stdexcept> //异常族的头文件
using namespace std;
double Div(double a, double b)
{
//invalid_argument p("Divide by zero...");
if( (-0.00000001 < b) && ( b < 0.00000001) )
{
/*
invalid_argument是一个异常类,invalid_argument("Divide by zero...")
是直接调用这个类的构造函数(后面是构造函数的参数,也是异常信息),
此时编译器产生一个临时对象,throw就是抛出了这个临时对象
*/
throw invalid_argument("Divide by zero...");
//throw p;
}
return a / b;
}
int main()
{
try
{
cout<<Div(1, 0)<<endl;
}
//这里使用引用是为了避免由于对象构造与拷贝的开销,使用引用就不会再重新创建一个对象进行拷贝了
catch(invalid_argument& error)
{
cout << error.what() << endl;//通过what成员函数获得异常信息
}
return 0;
}
注意:在catch语句后,可以使用引用参数,使用引用就避免了对象的构造和拷贝的开销,效率会高些!#include <iostream>
#include <stdexcept> //异常族的头文件
using namespace std;
class div_zero_error : public logic_error
{
public:
div_zero_error(const char* s) : logic_error(s)//初始化列表~~~
{
}
};
double Div(double a, double b)
{
//div_zero_error p("Divide by zero...");
if( (-0.00000001 < b) && ( b < 0.00000001) )
{
/*
div_zero_error是一个异常类,div_zero_error("Divide by zero...")
是直接调用这个类的构造函数(后面是构造函数的参数,也是异常信息),
此时编译器产生一个临时对象,throw就是抛出了这个临时对象
*/
throw div_zero_error("Divide by zero...");
//throw p;
}
return a / b;
}
int main()
{
try
{
cout<<Div(1, 0)<<endl;
}
//这里使用引用是为了避免由于对象构造与拷贝的开销,使用引用就不会再重新创建一个对象进行拷贝了
catch(exception& error) //使用exception类型 是为了接受各种类型的异常
{
cout << error.what() << endl;//通过what成员函数获得异常信息
}
return 0;
}
注意:第一,当希望通过标准库中的异常类族派生出自己的异常类的时候,首先要自己定义类并继承基类,这样自己的异常类中就继承了logic_error类的构造函数,这个带参的构造函数(即参数是字符串,用来保存异常信息的)是对应what()成员函数的。所以就出现了这样的语句,div_zero_error(const char* s) : logic_error(s) 这条语句很有意思,这条语句使用了构造函数的初始化参数列表!当创建div_zero_error类对象的时候,先接收构造函数的参数,且保存在s中,不管是从初始化列表的角度看,还是从父类构造函数的角度看,都是先调用logic_error类的构造函数,再调用div_zero_error类的构造函数,此时在调用logic_error类的构造函数的时候,就完成了对异常信息的保存!!!等于说把子类div_zero_error的构造函数的参数赋值给了父类logic_error的构造函数的参数,用于传递异常信息,即div_zero_error的构造函数的参数就是用来接收异常信息的!对于那些标准库中的其他子类,原理依然相同!原文:http://blog.csdn.net/mbh_1991/article/details/18994621