您的位置:首页 > 编程语言 > C语言/C++

C++异常的理解

2016-10-23 14:37 218 查看
错误处理技术

1.终止程序(段错误)

2.返回错误码

3.返回合法值

4.调用一个预先设置的出现错误时调的函数(回调函数)

异常处理

-当一个函数发现自己无法处理的错误时抛出异常,让函数的调用者直接或间接的处理这个问题。

异常的抛出和捕获

- 异常是通过抛出对象而引发的,对象的类型决定了应该激活哪个处理代码。

- 处理代码是与该对象类型匹配且离抛出异常位置最近的哪个

- 抛出异常后会释放局部存储对象,所处被抛出的对象叶欢给操作系统了,throw会初始化一个抛出特殊的异常对象副本(匿名对象),异常对象由编译管理,对象传给对应的catch处理后撤销。

栈展开

- 抛出异常的时候,暂停当前函数的执行,开始查找对应的匹配catch。

- 首先在throw本身是否在团员块内部,如果是查找catch,如果有匹配的,就处理;如果没有匹配的,则退出当前函数栈,继续在调用函数的栈中查找;如果到main函数的栈依旧没有找到匹配的,就终止程序。

异常捕获的匹配规则

-异常对象类型与catch的类型必须完全匹配

例外

1.从非const对象到const对象。

2.从派生类型到基类类型的转换。

3.数组转换为指向数组的指针,函数转换为指向函数的指针。

#include <iostream>
#include <string>
using namespace std;

class Exception
{
public :
Exception(int errId, const char * errMsg)
: _errId(errId )
, _errMsg(errMsg )
{}

void What () const
{
cout<<"errId:" <<_errId<< endl;
cout<<"errMsg:" <<_errMsg<< endl;
}
private :
int _errId ;       // 错误码
string _errMsg ;  // 错误消息
};

void Func1 (bool isThrow)
{
// ...
if (isThrow )
{
throw Exception (1, "抛出 Excepton对象" );
}
// ...

printf("Func1(%d)\n" , isThrow);
}

void Func2 (bool isThrowString, bool isThrowInt)
{
// ...
if (isThrowString )
{
throw string ("抛出 string对象" );
}
// ...
if(isThrowInt )
{
throw 7;
}

printf("Func2(%d, %d)\n" , isThrowString, isThrowInt );
}

void Func ()
{
try
{
Func1(false );
Func2(true , true);
}
catch(const string& errMsg)
{
cout<<"Catch string Object:" <<errMsg<< endl;
}
catch(int errId)
{
cout<<"Catch int Object:" <<errId<< endl;
}
catch(const Exception& e)
{
e.What ();
}
catch(...)
{
cout<<" 未知异常"<< endl;
}

printf ("Func()\n");
}

int main()
{
Func();

return 0;
}


运行结果如下:


异常的重新抛出

有可能单个catch不能完全处理一个异常,在进行一些校正处理后,希望再交给更外层的调用链函数来处理,catch则可以通过重新将异常传递给上层的函数来进行处理。

#include <iostream>
#include <string>
using namespace std;

class Exception
{
public :
Exception(int errId = 0, const char * errMsg = "" )
: _errId(errId )
, _errMsg(errMsg )
{}

void What () const
{
cout<<"errId:" <<_errId<< endl;
cout<<"errMsg:" <<_errMsg<< endl;
}
private :
int _errId ;       // 错误码
string _errMsg ;  // 错误消息
};

void Func1 ()
{
throw string ("Throw Func1 string");
}

void Func2 ()
{
try
{
Func1();
}
catch(string & errMsg)
{
cout<<errMsg <<endl;
Exception e (1, "Rethorw Exception");
throw e ;
// throw;
// throw errMsg;
}
}

void Func3 ()
{
try
{
Func2();
}
catch (Exception & e)
{
e.What ();
}
}
int main()
{
Func3();
return 0;
}


运行结果如下:



异常 构造函数&析构函数

构造函数完成对象的构造和初始化,要保证不在构造函数中抛出异常,否则可能导致对象不完整或没有完全初始化

析构函数 主要完成资源的清理,保证不在析构函数中抛出异常,否则导致资源泄漏(内存泄漏,句柄未关闭等)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: