关闭

C++异常参数传递和普通函数参数传递的区别

发表于:2013-3-19 09:58

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:侠骨豪情    来源:51Testing软件测试网采编

  从语法上看,在函数里声明参数与在catch子句中声明参数是一样的,catch里的参数可以是值类型,引用类型,指针类型。例如:

try
{
   .....
}
catch(A a)
{
}
catch(B& b)
{
}
catch(C* c)
{
}

  尽管表面是它们是一样的,但是编译器对二者的处理却又很大的不同。调用函数时,程序的控制权最终还会返回到函数的调用处,但是抛出一个异常时,控制权永远不会回到抛出异常的地方。

class A;
void func_throw()
 {
     A a;
     throw a;  //抛出的是a的拷贝,拷贝到一个临时对象里
 }
try
{
    func_throw();
}
catch(A a)  //临时对象的拷贝
{
}

  当我们抛出一个异常对象时,抛出的是这个异常对象的拷贝。当异常对象被拷贝时,拷贝操作是由对象的拷贝构造函数完成的。该拷贝构造函数是对象的静态类型(static type)所对应类的拷贝构造函数,而不是对象的动态类型(dynamic type)对应类的拷贝构造函数。此时对象会丢失RTTI信息。

  异常是其它对象的拷贝,这个事实影响到你如何在catch块中再抛出一个异常。比如下面这两个catch块,乍一看好像一样:

catch (A& w) // 捕获异常
{
 // 处理异常
 throw; // 重新抛出异常,让它继续传递
}
catch (A& w) // 捕获Widget异常
{
 // 处理异常
 throw w; // 传递被捕获异常的拷贝
}

  第一个块中重新抛出的是当前异常(current exception),无论它是什么类型。(有可能是A的派生类)

  第二个catch块重新抛出的是新异常,失去了原来的类型信息。

  一般来说,你应该用throw来重新抛出当前的异常,因为这样不会改变被传递出去的异常类型,而且更有效率,因为不用生成一个新拷贝。

  看看以下这三种声明:

catch (A w) ... // 通过传值
catch (A& w) ... // 通过传递引用
catch (const A& w) ... //const引用

31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号