throw 是C++中的关键字,用来抛出异常。如果不使用 throw 关键字,try 就什么也捕获不到;上节提到的 at() 函数在内部也使用了 throw 关键字来抛出异常。

throw 既可以用在标准库中,也可以用在自定义的函数中,抛出我们期望的异常。throw 关键字语法为:

throw exceptionData;

exceptionData 是“异常数据”的意思,它既可以是一个普通变量,也可以是一个对象,只要能在 catch 中匹配就可以。

下面的例子演示了如何使用 throw 关键字:

#include <iostream>
#include <string>
using namespace std;
char get_char(const string &, int);
int main(){
string str = "c plus plus";
try{
cout<<get_char(str, )<<endl;
cout<<get_char(str, )<<endl;
}catch(int e){
if(e==){
cout<<"Index underflow!"<<endl;
}else if(e==){
cout<<"Index overflow!"<<endl;
}
}
return ;
}
char get_char(const string &str, int index){
int len = str.length();
if(index < )
throw ;
if(index >= len)
throw ;
return str[index];
}

在 get_char() 函数中,我们使用了 throw 关键字,如果下标越界,就会抛出一个 int 类型的异常:如果是下溢,异常数据的值为 1;如果是上溢,异常数据的值为 2。在 catch 中,将捕获 int 类型的异常,然后根据异常数据输出不同的提示语。

不被建议的用法

throw 关键字除了可以用在函数体中抛出异常,还可以用在函数头和函数体之间,指明函数能够抛出的异常类型。有些文档中称为异常列表。例如:

double func (char param) throw (int);

这条语句声明了一个名为 func 的函数,它的返回值类型为 double,有一个 char 类型的参数,并且只能抛出 int 类型的异常。如果抛出其他类型的异常,try 将无法捕获,只能终止程序。

如果希望能够抛出多种类型的异常,可以用逗号隔开:

double func (char param) throw (int, char, exception);

如果不希望限制异常类型,那么可以省略:

double func (char param) throw ();

如此,func() 函数可以抛出任何类型的异常,try 都能捕获到。

更改上例中的代码:

#include <iostream>
#include <string>
using namespace std;
char get_char(const string &, int) throw(char, exception);
int main(){
string str = "c plus plus";
try{
cout<<get_char(str, 2)<<endl;
cout<<get_char(str, 100)<<endl;
}catch(int e){
if(e==1){
cout<<"Index underflow!"<<endl;
}else if(e==2){
cout<<"Index overflow!"<<endl;
}
}
return 0;
}
char get_char(const string &str, int index) throw(char, exception){
int len = str.length();
if(index < 0)
throw 1;
if(index >= len)
throw 2;
return str[index];
}

在使用 GCC 的 IDE 中运行代码,执行到第 12 行时程序会崩溃。虽然 func 函数检测到下标越界,知道发生了异常,但是由于 throw 限制了函数只能抛出 char、exception 类型的异常,所以 try 将捕获不到异常,只能交给系统处理,终止程序。

需要说明的是,C++标准已经不建议这样使用 throw 关键字了,因为各个编译器对 throw 的支持不同,有的直接忽略,不接受 throw 的限制,有的将 throw 作为函数签名,导致引用函数时可能会有问题。上面的代码在 GCC 下运行时会崩溃,在 VS 下运行时则直接忽略 throw 关键字对异常类型的限制,try 可以正常捕获到 get_char() 抛出的异常,程序并不会崩溃。

C++学习40 抛出自己的异常的更多相关文章

  1. @Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常。

    @Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationEx ...

  2. shiro配置unauthorizedUrl,无权限抛出无权限异常,但是不跳转

    在使用shiro配置无授权信息的url的时候,发现这样的一个scenario,配置好unauthorizedUrl后仍然无法跳转,然后就在网上开始找,找了原因以及解决方案 原因,先post一个源码: ...

  3. c# throw抛出上一个异常

    catch(exception e) { throw; } 不仅抛出这次的异常,也抛出之前的异常. 用法示例:函数A调用函数B,A用到此throw时,B中发生的异常也会继承过来. catch(exce ...

  4. 【JAVASE】Java同一时候抛出多个异常

    Java有异常抛出后.跳出程序.一般无法运行接下来的代码. 大家做登陆功能.常常会实username和password的登陆校验,username或者password错误.假设通常是提示usernam ...

  5. [Go] 如何正确地 抛出 错误 和 异常(error/panic/recover)?

    序言 错误 和 异常 是两个不同的概念,非常容易混淆.很多程序员习惯将一切非正常情况都看做错误,而不区分错误和异常,即使程序中可能有异常抛出,也将异常及时捕获并转换成错误.从表面上看,一切皆错误的思路 ...

  6. servlet 和filter 抛出404等异常

    1. servlet抛出错误代码异常,如404 public void doGet(HttpServletRequest request, HttpServletResponse response) ...

  7. JAVA 抛出与声明异常

    在编程过程中,我们往往会遇到这种情况,在当前环境中无法解决,比如用户传入的参数错误,IO设备问题等.此时,就要从当前环境中抛出异常提交给上级来处理. 在JAVA语言中,使用throw关键字来抛出异常. ...

  8. WebService如何抛出干净的异常

    转载:http://www.cnblogs.com/ahdung/p/3953431.html 说明:[干净]指的是客户端在捕获WebService(下称WS)抛出的异常时,得到的ex.Message ...

  9. [SQL SERVER] - 还原数据库备份(SQL脚本),抛出 "System.OutOfMemoryException" 异常之解决

    背景 在 Microsoft SQL Server 2016 的查询窗体中,直接还原备份数据库的 SQL 脚本(99MB),抛出 Cannot execute script 异常: 原因 相关资料说: ...

随机推荐

  1. C# Timer用法及实例详解

    C# Timer用法有哪些呢?我们在使用C# Timer时都会有自己的一些总结,那么这里向你介绍3种方法,希望对你了解和学习C# Timer使用的方法有所帮助. 关于C# Timer类  在C#里关于 ...

  2. linux服务之upstart与systemd

    http://blog.fens.me/linux-upstart/ rpm -ql initscripts|more [root@84-monitor init]# rpm -qf /etc/ini ...

  3. linux工具类之流量监视

    iptraf        好用 yum install iptrafiptraf  is an ncurses-based IP LAN monitor that generates various ...

  4. Why we made vorlon.js and how to use it to debug your JavaScript remotely

    Vorlon.js is powered by node.JS, socket.io, and late-night coffee. I would like to share with you wh ...

  5. python3_RoboBrowser_test

    python3_RoboBrowser_test selenium库作为交互是非常方便的,但是却大大加长了加载的时间,例如需要渲染网址,加载js,造成在爬虫过程中时间变长. 因此找到一个虚拟的浏览器, ...

  6. 【性能诊断】十一、性能问题综合分析(案例2,windbg、wireshark)

    [问题描述]:       前段时间有一项目反馈,常用的审批功能有时的响应较慢,多个管理员功能不定期的出现客户端无响应的状况,并且管理员功能一旦出现卡死,也会影响到普通的业务用户致使很多用户无法操作. ...

  7. ASP.NET 4.0的ClientIDMode属性

    时光流逝,我们心爱的ASP.NET也步入了4.0的时代,微软在ASP.NET 4.0中对很多特性做了修改.比如我将要讨论的控件ID机制就是其中之一. 在ASP.NET 4.0之前我们总是要为控件的Cl ...

  8. python 批量请求url

    import urllib2 from urllib import quote f = open("data.in", "r") out = file(&quo ...

  9. 在数据库查询时解决大量in 关键字的方法

    有时候在前台界面需要批量处理一些数据时,经常要用到update table set fields=value where keyid in ('1','2',....) 但如果这个数据量如果超过100 ...

  10. Effective Java 学习笔记----第7章 通用程序设计

    第7章 通用程序设计 第29条 将局部变量的作用域最小化     使一个局部变量的作用域最小化,最有力的技术室在第一次使用它的地方声明.   第30条 了解和使用库      效率提高.如果你不知道库 ...