热门标签 | HotTags
当前位置:  开发笔记 > IOS > 正文

C++异常的详细介绍

这篇文章主要介绍了C++异常的详细介绍的相关资料,希望通过本文大家能够掌握C++异常的使用方法,需要的朋友可以参考下

C++ 异常的详解

程序有时会遇到运行阶段错误,导致程序无法正常执行下去。c++异常为处理这种情况提供了一种功能强大的而灵活的工具。异常是相对比较新的C++功能,有些老编译器可能没有实现。另外,有些编译器默认关闭这种特性,我们可能需要使用编译器选项来启用它。

一、异常机制的使用

异常提供了将控制程序的一个部分传递到另一部分的途径。对异常的处理有3个组成部分:

引发异常
使用处理程序捕获异常
使用try块

示例代码:

#include "stdafx.h"
#include 
double hmean(double a, double b);
int main()
{
  double x, y, z;
  std::cout <<"Enter two numbers: ";
  while (std::cin >> x >> y) {
    try
    {
      z = hmean(x, y);
    }
    catch(const char *s ){
      std::cout <: ";
  }
  std::cout <<"Bye! \n";
  system("pause");
  return 0;
}

double hmean(double a, double b) {
  if (a == -b) {
    throw "bad hmean() arguments a= -b not allowed";

  }
  return 2.0 *a*b / (a + b);
}

Enter two numbers: 3 6
Harmonic mean of 3 and 6 is 4
Enter next set of numbers : 10 -10
bad hmean() arguments a= -b not allowed
 Enter a new pair of numbers: q
Bye!
请按任意键继续. . .

程序说明:

try块:

   try
    {
      z = hmean(x, y);
    }

引发异常的代码:

if (a == -b) {
    throw "bad hmean() arguments a= -b not allowed";

  }

执行throw语句类似于执行返回语句,因为他也将终止函数的执行;但throw不是讲控制权返回给调用程序,而是导致程序沿函数调用序列后退,知道找到包含try块的函数。

处理程序(或catch块):

catch(const char *s ){
      std::cout <

二、将对象用作异常类型

通常,引发异常的函数将传递一个对象。这样做的重要优点之一是,可以使用不同的异常类型来区分不同的函数在不同情况下引发的异常。另外,对象可以携带信息,程序员可以根据这些信息来确定引发异常的原因。同时,catch块可以根据这些信息来决定采取什么样的措施。

示例:

exc_mean.h

#include "stdafx.h"
#include 

class bad_hmean
{
private:
  double v1;
  double v2;
public :
  bad_hmean(double a = 0, double b = 0) :v1(a), v2(b) {}
  void mesg();
};
inline void bad_hmean::mesg() 
{
  std::cout <<"hmean ( " <=0 \n";
}

测试代码:

#include "stdafx.h"
#include 
#include 
#include "exc_mean.h"

double hmean(double a, double b);
double gmean(double a, double b);

int main()
{
  using std::cout;
  using std::cin;
  using std::endl;

  double x, y, z;
  1 >> 2;
  cout <<"Enter two numbers ";
  while (cin >> x >> y)
  {
    try 
    {
      z = hmean(x, y);
      cout <<"Harmonic mean of " <:";
    }
    catch (bad_hmean & bg)
    {
      bg.mesg();
      cout <<"Try again. \n";
      continue;
    }
    catch (bad_gmean & hg)
    {
      cout <:5 -5
hmean ( 5 ,-5) ;invalid argumnents: a =-b
Try again.
5 -2
Harmonic mean of 5 and -2 is -6.66667
gmean() arguments shoud be >=0
Value used: 5 ,-2
Sorry, you don't get to play any more .
 Bye!
请按任意键继续. . .

三、异常规范

异常规范是C++98的一项功能,但c++11将其摒弃了。这意味着c++11仍然处于标准之中,但以后可能会从标准中剔除,因此不建议使用它。

异常规范示例:

double harm(double a ) throw(bad_thing);//可能会抛出 bad_thing异常
double marm(double ) throw() ;//不抛出异常

异常规范的作用:

1、告诉用户可能需要使用try块,然而这项功能也可使用注释轻松完成。

2、让编译器添加执行运行阶段检查代码,检查是否违反了异常规范,然而这很难检查,例如marm可能不会引发异常,但它可能调用一个函数,而这个函数调用另一个函数引发了异常

总之最好不要使用这项功能,c++11也建议忽略异常规范

然而c++11确实支持一种特殊的异常规范,可使用关键字noexcept

例如

double marm() noexcept;

四、栈解退

假设函数由于异常(而不是由于返回)而终止,则程序也将释放栈中的内存,但不会师范栈的第一个返回地址后停止,而是继续释放栈,直到找到一个位于Try块的返回地址。随后,控制权将转到块尾的异常处理程序,而不是函数调用后面的第一条语句。这个过程叫做栈解退。

五、exception类

较新的C++编译器将异常合并到语言中,例如,为支持该语言,exception头文件(以前为exception.h 或except.h)定义了 exception类,c++可以把它用作其他异常类的基类。

头文件 exceptionhe 和 stdexcept 定义了一些常用的异常类

有:logic_error、runtime_error、domain_error 等

六、意外异常与未捕获异常处理

异常引发后,在两种情况下,会导致问题。首先,如果它是在带异常规范的函数中引发的,则必须与规范列表的某种异常匹配(在继承层次机构中,类类型与这个类与其派生的对象匹配),否则成为意外异常。在默认情况下,这将导致程序异常终止(虽然C++11摒弃了异常规范,但仍支持它,且有些现有代码使用了它)如果异常不是在函数中引发的(或者函数没有异常规范),则必须捕获它,如果没有捕获(在没有try块或没有匹配的catch块时,将出现这种情况),则异常被称未捕获异常。这将导致程序异常终止。然而可以修改程序对意外异常和为捕获异常的反应。

未捕获异常:

未捕获异常不会导致程序立即异常中终止,相反,程序将首先调用函数terminate()。在默认情况下terminate()调用abort()函数。可以指定terminate()应调用的函数(而不是abort())来修改terminate()的这种行为。为此,可调用set_terminate()函数。set_terminate()和terminate()都是在头文件exception中声明的:

typedef void (*terminate_handle)() ;
terminate_handle set_terminate(terminate_handle f) throw();//c++ 98
terminate_handle set_terinate(terminate_handle f) noexcept; //c++11
void teminate(); //c++98
void teminate() noexcept ; //c++11

示例:

void myQuit()
{
  std::cout <<"Terminating due to uncaught exception \n";

  system("pause");
}

在程序开始时执行:
set_terminate(myQuit);

意外异常

如果发生意外异常,程序将调用unexcepted()函数,这个函数将调用teminate(),后者默认滴啊用abort()。和set_terminate()函数一样,也有一个可用于修改unexcepted()的行为的set_unexpeceted()函数。这些函数也是在头文件exception中声明的:

typedef void (* unexpected_handle)();
unexpected_handle set_unexpected(unexpected_handle f) throw();//c++98
unexpected_handle set_unexpected(unexpected_handle f) noexpect;//c++11
void unexpected(); c++ 98
void unexpected() noexcept ;//c+ 0x

使用如下:

void myUnexpected() {
  throw std::bad_exception(); // or just throw ;
}
在程序开始时:
set_unexpected(myUnexpected);

我在vs 2015下测试,并未实现这种功能,必须显示调用terminate() 和 unexpected();

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


推荐阅读
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • 程序员妻子吐槽:丈夫北漂8年终薪3万,存款情况令人意外
    一位程序员的妻子在网上分享了她丈夫在北京工作八年的经历,月薪仅3万元,存款情况却出乎意料。本文探讨了高学历人才在大城市的职场现状及生活压力。 ... [详细]
  • 本题探讨了一种字符串变换方法,旨在判断两个给定的字符串是否可以通过特定的字母替换和位置交换操作相互转换。核心在于找到这些变换中的不变量,从而确定转换的可能性。 ... [详细]
  • 本文探讨了如何像程序员一样思考,强调了将复杂问题分解为更小模块的重要性,并讨论了如何通过妥善管理和复用已有代码来提高编程效率。 ... [详细]
  • 深入理解Java中的volatile、内存屏障与CPU指令
    本文详细探讨了Java中volatile关键字的作用机制,以及其与内存屏障和CPU指令之间的关系。通过具体示例和专业解析,帮助读者更好地理解多线程编程中的同步问题。 ... [详细]
  • 深入理解C++中的KMP算法:高效字符串匹配的利器
    本文详细介绍C++中实现KMP算法的方法,探讨其在字符串匹配问题上的优势。通过对比暴力匹配(BF)算法,展示KMP算法如何利用前缀表优化匹配过程,显著提升效率。 ... [详细]
  • 理解存储器的层次结构有助于程序员优化程序性能,通过合理安排数据在不同层级的存储位置,提升CPU的数据访问速度。本文详细探讨了静态随机访问存储器(SRAM)和动态随机访问存储器(DRAM)的工作原理及其应用场景,并介绍了存储器模块中的数据存取过程及局部性原理。 ... [详细]
  • 利用存储过程构建年度日历表的详细指南
    本文将介绍如何使用SQL存储过程创建一个完整的年度日历表。通过实例演示,帮助读者掌握存储过程的应用技巧,并提供详细的代码解析和执行步骤。 ... [详细]
  • 自学编程与计算机专业背景者的差异分析
    本文探讨了自学编程者和计算机专业毕业生在技能、知识结构及职业发展上的不同之处,结合实际案例分析两者的优势与劣势。 ... [详细]
  • SQLite 动态创建多个表的需求在网络上有不少讨论,但很少有详细的解决方案。本文将介绍如何在 Qt 环境中使用 QString 类轻松实现 SQLite 表的动态创建,并提供详细的步骤和示例代码。 ... [详细]
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
  • 阅读本文大约需要3分钟。微信8.0版本的发布带来了许多令人振奋的新功能,如烟花特效和改进的悬浮窗,引发了用户的热烈反响。 ... [详细]
  • 深入理解Java泛型:JDK 5的新特性
    本文详细介绍了Java泛型的概念及其在JDK 5中的应用,通过具体代码示例解释了泛型的引入、作用和优势。同时,探讨了泛型类、泛型方法和泛型接口的实现,并深入讲解了通配符的使用。 ... [详细]
  • 作为一名程序员,从大学步入职场后,常常感受到一种难以言喻的空虚感。这种感觉或许源于对生活的不满、职业发展的瓶颈,或是日常琐事带来的压力。本文将深入探讨这种复杂的情感,并尝试寻找解决之道。 ... [详细]
  • 深入解析:阿里实战 SpringCloud 微服务架构与应用
    本文将详细介绍 SpringCloud 在微服务架构中的应用,涵盖入门、实战和案例分析。通过丰富的代码示例和实际项目经验,帮助读者全面掌握 SpringCloud 的核心技术和最佳实践。 ... [详细]
author-avatar
mobiledu2502885407
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有