第01节:概览异常


QuotientWithException.cpp

#include <iostream>
using namespace std;int main() {// Read two intergerscout << "Enter two integers: ";int number1, number2;cin >> number1 >> number2;try {if (number2 == 0)throw number1;cout << number1 << " / " << number2 <<" is "  << (number1 / number2) << endl;}catch (int e) {cout << "Exception: an integer " << e <<" cannot be divided by zero" << endl;}cout << "Execution continues ..." << endl;return 0;
}


第02节:异常处理机制的优点


QuotientWithFunction.cpp

#include <iostream>
using namespace std;int quotient(int number1, int number2) {if (number2 == 0)throw number1;return number1 / number2;
}int main() {// Read two intergerscout << "Enter two integers: ";int number1, number2;cin >> number1 >> number2;try {int result = quotient(number1, number2);cout << number1 << " / " << number2 << " is "<< result << endl;}catch (int e) {cout << "Exception from function: an integer " << e <<" cannot be divided by zero" << endl;}cout << "Execution continues ..." << endl;
}

第03节:异常类


#include <iostream>
using namespace std;int main() {try   {for (int i = 1; i <= 100; i++)  {new int[70000000];cout << i << " arrays have been created" << endl;}}catch (bad_alloc &e) {cout << "Exception: " << e.what() << endl;}return 0;
}

#include <typeinfo>
#include "DerivedCircle.h"
#include "Rectangle.h"
#include <iostream>
using namespace std;int main() {try   {Rectangle r(3.0, 4.0);Circle & c = dynamic_cast<Circle&>(r);}catch (bad_cast &e)   {cout << "Exception: " << e.what() << endl;}
}

#include <typeinfo>
#include <iostream>
#include <stdexcept>
using namespace std;int quotient(int number1, int number2)
{if (number2 == 0)throw runtime_error("Runtime error in quotient");return number1 / number2;
}int main()
{// Read two intergerscout << "Enter two integers: ";int number1, number2;cin >> number1 >> number2;try{int result = quotient(number1, number2);cout << number1 << " / " << number2 << " is "<< result << endl;}catch (exception &e){cout << "Exception: " << e.what() << endl;cout << "Exception type: " << typeid(e).name() << endl;}cout << "Execution continues ..." << endl;return 0;
}


u09s03 - runtime_error与logic_error的使用区别是什么?
你能说说 runtime_error 与 logic_error 这两个异常的主要区别是什么?

何时应该使用 runtime_error 而何时又该使用 logic_error?
答:C++0x Standard says (clause 19.2):上是这么描述的

  1. In the error model reflected in these classes (i.e. the exception types), errors are divided into two broad categories: logic errors and runtime errors.

  2. The distinguishing characteristic of logic errors is that they are due to errors in the internal logic of the program. In theory, they are preventable.

逻辑错误

  1. By contrast, runtime errors are due to events beyond the scope of the program. They cannot be easily predicted in advance.

程序的作用范围造成的( the “scope” is defined as the library code’s expectations, not your program’s design)

在Cpp标准上也有这样的描述:

logic_error
“The class logic_error defines the type of objects thrown as exceptions to report errors presumably detectable before the program executes, such as violations of logical preconditions or class invariants.”

在程序执行前,去对一个逻辑上的先决条件进行判断

runtime_error
“The class runtime_error defines the type of objects thrown as exceptions to report errors presumably detectable only when the program executes.”

在程序执行的过程中,报出错误。

比如,runtime_error的overflow_error是在程序进行计算(运行)的时候发现的。

而,logic_error的out_of_range,以vector为例,虽然也是程序执行过程中发现的,但是并没有去取vector中真实数据,而是先检查了这个“取操作”是否可行。

(by wuqijssn)

第04节:自定义异常类


Triangle.h

#include "AbstractGeometricObject.h"
#include "TriangleException.h"
#include <cmath>class Triangle: public GeometricObject
{
public:Triangle(double side1, double side2, double side3){if (!isValid(side1, side2, side3))throw TriangleException(side1, side2, side3);this->side1 = side1;this->side2 = side2;this->side3 = side3;}double getSide1(){return side1;}double getSide2(){return side2;}double getSide3(){return side3;}double setSide1(double side1){if (!isValid(side1, side2, side3))throw TriangleException(side1, side2, side3);this->side1 = side1;}double setSide2(double side2){if (!isValid(side1, side2, side3))throw TriangleException(side1, side2, side3);this->side2 = side2;}double setSide3(double side3){if (!isValid(side1, side2, side3))throw TriangleException(side1, side2, side3);this->side3 = side3;}double getPerimeter(){return side1 + side2 + side3;}double getArea(){double s = getPerimeter() / 2;return sqrt(s * (s - side1) * (s - side2) * (s - side3));}private:double side1, side2, side3;bool isValid(double side1, double side2, double side3){return (side1 < side2 + side3) && (side2 < side1 + side3) &&(side3 < side1 + side2);}
};

TriangleException.h

#include <stdexcept>
using namespace std;class TriangleException: public logic_error
{
public:TriangleException(double side1, double side2, double side3): logic_error("Invalid triangle"){this->side1 = side1;this->side2 = side2;this->side3 = side3;}double getSide1(){return side1;}double getSide2(){return side2;}double getSide3(){return side3;}private:double side1, side2, side3;
};

TestTriangle.cpp

#include <iostream>
#include "Triangle.h"
using namespace std;int main() {try{Triangle triangle(2, 1, 1);cout << triangle.getPerimeter() << endl;cout << triangle.getArea() << endl;}catch (TriangleException &ex){cout << ex.getSide3();}
}

第05节:多重异常捕获



NonPositiveSideException.h

#include <stdexcept>
using namespace std;class NonPositiveSideException: public logic_error {
private:double side;public:NonPositiveSideException(double side): logic_error("Non-positive side") {this->side = side;}double getSide() {return side;}
};

NewTriangle.h

#include "AbstractGeometricObject.h"
#include "TriangleException.h"
#include "NonPositiveSideException.h"
#include <cmath>class Triangle: public GeometricObject
{
public:Triangle(){side1 = side2 = side3 = 1;}Triangle(double side1, double side2, double side3)throw (NonPositiveSideException, TriangleException){check(side1);check(side2);check(side3);if (!isValid(side1, side2, side3))throw TriangleException(side1, side2, side3);this->side1 = side1;this->side2 = side2;this->side3 = side3;}double getSide1(){return side1;}double getSide2(){return side2;}double getSide3(){return side3;}void setSide1(double side1){check(side1);if (!isValid(side1, side2, side3))throw TriangleException(side1, side2, side3);this->side1 = side1;}void setSide2(double side2){check(side2);if (!isValid(side1, side2, side3))throw TriangleException(side1, side2, side3);this->side2 = side2;}void setSide3(double side3){check(side3);if (!isValid(side1, side2, side3))throw TriangleException(side1, side2, side3);this->side3 = side3;}double getPerimeter(){return side1 + side2 + side3;}double getArea(){double s = getPerimeter() / 2;return sqrt(s * (s - side1) * (s - side2) * (s - side3));}private:double side1, side2, side3;bool isValid(double side1, double side2, double side3){return (side1 < side2 + side3) && (side2 < side1 + side3) &&(side3 < side1 + side2);}void check(double side) throw (NonPositiveSideException){if (side <= 0)throw NonPositiveSideException(side);}
};

MultipleCatchDemo.cpp

#include <iostream>
#include "NewTriangle.h"
using namespace std;int main()
{try{cout << "Enter three sides: ";double side1, side2, side3;cin >> side1 >> side2 >> side3;Triangle triangle(side1, side2, side3);cout << "Perimeter is " << triangle.getPerimeter() << endl;cout << "Area is " << triangle.getArea() << endl;}catch (NonPositiveSideException &ex){cout << ex.what();cout << " the side is " << ex.getSide() << endl;}catch (TriangleException &ex){cout << ex.what();cout << " three sides are " << ex.getSide1() << " "<< ex.getSide2() << " " << ex.getSide3() << endl;}
}



u09s05 - catch块的参数类型可以不用引用类型吗?
我们给的很多例子中, catch () 括号中的异常对象参数都是引用类型。

catch () 括号中的异常对象参数可否不用引用类型?

catch () 括号中的异常对象参数可否使用指针类型,比如: catch (Exception* e)

在多重异常捕获的代码中,若几个catch()括号中的参数是某个类继承链中不同层次的类的对象,此时括号中的参数可否不用引用类型?为什么?
答:

  1. 可以不用引用类型。

  2. 如果在try块里面抛出的是exception指针,那么catch的异常参数也可以是指针。但是由于内存管理等等问题,c++ primer推荐用reference。

  3. 如果一个派生类Exception不被以引用传出到一个catch基类Exception块,那么有关派生类Exception的内容将会丢失,再将其抛出的时候就外部调用函数就只能以基类catch了。(by kevw22)

第06节:异常传播


u09s06 - 异常传播的形象例子?
你能给出一个比较形象的描述异常传播的例子吗?比如《果壳中的宇宙》?比如虫子钻洋葱?
答:比如DELL客户维修站,客户的灵越系列5547的屏幕出现了花屏,县城基站的维修不了,往市里,市里的小哥一看,卧槽,这什么问题,去找省里的老大哥,哎哟妈呀,这啥玩意了,不行,被操哭了,再去找总部的老头儿终于搞定了。exception发现了,然后解决方案一级一级往下传,因为县里,市里,省里的哥们都没辙,所以他们只能返回结果。(by 喵星折腾党党…)

第07节:重抛异常 以及 异常规约


RethrowExceptionDemo.cpp

#include <iostream>
#include <stdexcept>
using namespace std;int f1() throw() {try {throw runtime_error("Exception in f1");}catch (exception& ex) {cout << "Exception caught in function f1" << endl;cout << ex.what() << endl;throw; // rethrow the exception}
}int main() {try {f1();}catch (exception& ex) {cout << "Exception caught in function main" << endl;cout << ex.what() << endl;}
}

崔毅东 C++程序设计入门(下) 第9单元:白公曾咏牡丹芳,一种鲜妍独“异常” 笔记相关推荐

  1. 崔毅东 C++程序设计入门(下) 第11单元:工欲善其事必先利其器 – 标准模板库

    第01节:STL基础 #include <iostream> #include <vector> #include <list> #include <dequ ...

  2. 崔毅东 C++程序设计入门(上) 第5单元:万类霜天竞自由 – 对象和类的更多内容 笔记

    第01节:不可变对象.不可变类:避免多次声明 Date1.h class Date { public:Date(int newYear, int newMonth, int newDay);//Dat ...

  3. 程序设计入门——C语言 习题汇总

    <img width="108" height="40" alt="浙江大学" src="http://imgsize.ph ...

  4. 【转】Unix环境高级程序设计入门----文件系统的相关编程(上)

    Unix环境高级程序设计入门 ----文件系统的相关编程(上) 一.关于目录 不管是何种操作系统,一提到其中的文件系统首先想到的自然是目录和文件.在Unix系统中一切皆可视为文件,目录是一种特殊的文件 ...

  5. 汇编程序设计入门(安装+debug调试实例)

    汇编程序设计入门(安装+debug调试实例) 一.汇编环境安装 1.安装dosbox https://www.dosbox.com/download.php?main=1 2.下载和安装masm ht ...

  6. Ajax程序设计入门

    Ajax程序设计入门 一.使用Ajax的主要原因 1.通过适当的Ajax应用达到更好的用户体验: 2.把以前的一些服务器负担的工作转嫁到客户端,利于客户端闲置的处理能力来处理,减轻服务器和带宽的负担, ...

  7. C语言程序设计入门教程

    C语言程序设计入门教程 目录 语言分类 C语言特点 最简单的C语言程序 注释方式 C语言程序的结构 程序设计的任务阶段 选择结构程序设计 关系运行算符 逻辑运算符 switch语句 条件运算符 数据类 ...

  8. 机器人程序设计入门(C++/Arduino/ROS)(转载2020版)

    本文主要介绍机器人程序设计入门的安装和配置,并通过简洁的示例演示基于Arduino和ROS构建的机器人物联网系统雏形.Arduino和ROS都支持使用C++进行程序设计. ROS+Arduino 安装 ...

  9. ObjectARX程序设计入门

    ObjectARX程序设计入门--1.图形数据库操作 AutoCAD图形实际上是一系列存放在一个AcDbDatabase类型的数据库中的AcDb对象.AcDbDatabase数据库中所有的对象都有一个 ...

最新文章

  1. 详解SQL中的触发器
  2. java final关键字_终于明白 Java 为什么要加 final 关键字了!
  3. hdu 2612(bfs)Find a way
  4. ssh中添加隧道,访问目标机器上的地址
  5. css 首字下沉 错位,css+div错位问题的修复小结
  6. java中functional interface的分类和使用
  7. php spl_autoload_register() 函数
  8. java 素数欧拉筛选_[C++]欧拉素数筛的理解与实现
  9. Git submodule 特性
  10. mysql query语句_使用mysql_query()函数执行SQL语句
  11. Git分布式版本控制
  12. 极路由 安装php,极路由B70刷固件详细步骤说明
  13. 第三次修正打坐的姿势
  14. 宇宙APP简单的性能测试
  15. 《你的降落伞是什么颜色》
  16. SVN提交失败 can‘t open file‘\db\txn-current-lock’
  17. 哪里买. com最便宜?
  18. 2022年 《三国演义》手摘
  19. 模电电路笔记———同向比例放大电路的使用
  20. 22年蓝桥杯青蛙过河问题

热门文章

  1. 同指数幂相减公式_同底指数加减运算法则
  2. 德国金融监管机构就区块链证券监管发布公告
  3. 递归解决年龄问题---c语言实现
  4. sciTE的一些设置
  5. 覆盖20个主流Niche高DA可投稿的谷歌博客外链分享
  6. 一篇小文章了解企业的敏捷开发流程
  7. openzipkin/brave初步了解
  8. 手机连过的WIFI密码忘了怎么办?
  9. 浅议大数据时代下消防工作、生活和思维的变革
  10. IAR 配置ICF跟项目走