当前位置: 首页 > news >正文

兰州装修公司排名前十seo怎么优化软件

兰州装修公司排名前十,seo怎么优化软件,贵州省住房与城乡建设部网站,asp.net 网站访问量目录 1、异常的概念及使用 1.1 异常的概念 1.2 异常的抛出和捕获 1.3 栈展开 1.4 查找匹配的处理代码 1.5 异常的重新抛出 1.6 异常的安全问题 1.7 异常的规范 2、标准库的异常(了解) 1、异常的概念及使用 1.1 异常的概念 C语言,出错了,就报错…

目录

1、异常的概念及使用

1.1 异常的概念

1.2 异常的抛出和捕获

1.3 栈展开

1.4 查找匹配的处理代码

1.5 异常的重新抛出

1.6 异常的安全问题

1.7 异常的规范

2、标准库的异常(了解)


1、异常的概念及使用

1.1 异常的概念

C语言,出错了,就报错误码,还要去查询错误信息,比较麻烦。错误处理与正常逻辑混杂,容易遗漏检查。

C++,出错了,就(throw)抛出一个异常对象,包含更全面的错误信息,并且(try)检测错误和(catch)处理错误,分开进行

1.2 异常的抛出和捕获

当程序出现问题时,可以通过抛出(throw一个异常对象来触发异常处理机制。该对象的类型及当前的调用链共同决定了哪个catch处理此异常

异常处理流程

  1. 匹配规则
    被选中的处理代码是调用链中与该异常对象类型匹配(通过类型匹配规则),且距离抛出位置最近catch

  2. 信息传递
    通过异常对象成员变量返回what()的字符串传递错误信息

  3. 控制流转移

    • throw执行时其后的语句不再执行

    • 程序throw跳转匹配的catch,该catch可能在当前函数或调用链上游的某个函数中。

    • 控制权转移意味着:

      • 调用链中的函数可能提前退出(函数栈帧提前销毁)(栈展开,Stack Unwinding)。

      • 栈上已构造的局部对象会按创建顺序的逆序销毁(RAII保证)。

  4. 异常对象生命周期

    • 因为异常对象是局部的(类似函数值返回的临时对象),会调用移动构造,(若没有移动构造,就调用拷贝构造)。

    • 移动(或复制)对象在匹配的catch块结束时 销毁

1.3 栈展开

抛出异常后,程序暂停当前函数的执行

如果 throw try 块内部查找匹配的 catch 语句如果匹配的,则跳到 catch 的地方进行处理

如果当前函数没有 try/catch 子句,或者有 catch 子句但是类型不匹配,则退出当前函数,继续在外层调用函数链中查找,上述查找的 catch 过程被称为栈展开

如果到达 main 函数,依旧没有找到匹配的 catch 子句,程序会调用标准库的 terminate 函数终止程序

如果找到匹配的 catch 子句处理后当前 catch 子句后面的代码继续执行

1.4 查找匹配的处理代码

一般情况下,抛出对象catch类型匹配的,如果有多个类型匹配的,就选择最近的catch

允许一些例外类型转换:

非常量 -> 常量(即权限缩小),

数组->数组元素的指针

函数->函数指针

派生类->基类,这个非常实用

如果到main函数异常仍旧没有被匹配就会终止程序我们是不期望程序终止,所以一般main函数中最后都会使用catch(...),它可以捕获任意类型的异常但是不知道异常错误是什么

#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include <ctime>
#include <cstdlib>// 一般大型项目程序才会使用异常,下面我们模拟设计一个服务的几个模块
// 每个模块的异常都是 Exception 的派生类,每个模块可以添加自己的数据
// 最后捕获时,我们捕获基类就可以class Exception {
public:Exception(const std::string& errmsg, int id): _errmsg(errmsg), _id(id) {}virtual std::string what() const {return _errmsg;}int getid() const {return _id;}protected:std::string _errmsg;int _id;
};class SqlException : public Exception {
public:SqlException(const std::string& errmsg, int id, const std::string& sql): Exception(errmsg, id), _sql(sql) {}std::string what() const override {std::string str = "SqlException:";str += _errmsg;str += "->";str += _sql;return str;}private:const std::string _sql;
};class CacheException : public Exception {
public:CacheException(const std::string& errmsg, int id): Exception(errmsg, id) {}std::string what() const override {std::string str = "CacheException:";str += _errmsg;return str;}
};class HttpException : public Exception {
public:HttpException(const std::string& errmsg, int id, const std::string& type): Exception(errmsg, id), _type(type) {}std::string what() const override {std::string str = "HttpException:";str += _type;str += ":";str += _errmsg;return str;}private:const std::string _type;
};void SQLMgr() {if (rand() % 7 == 0) {throw SqlException("权限不足", 100, "select * from name = '张三'");} else {std::cout << "SQLMgr 调用成功" << std::endl;}
}void CacheMgr() {if (rand() % 5 == 0) {throw CacheException("权限不足", 100);} else if (rand() % 6 == 0) {throw CacheException("数据不存在", 101);} else {std::cout << "CacheMgr 调用成功" << std::endl;}SQLMgr();
}void HttpServer() {if (rand() % 3 == 0) {throw HttpException("请求资源不存在", 100, "get");} else if (rand() % 4 == 0) {throw HttpException("权限不足", 101, "post");} else {std::cout << "HttpServer 调用成功" << std::endl;}CacheMgr();
}int main() {srand(time(0));while (1) {std::this_thread::sleep_for(std::chrono::seconds(1));try {HttpServer();}catch (const Exception& e) {  // 这里捕获基类,基类对象和派生类对象都可以被捕获std::cout << e.what() << std::endl;}catch (...) {std::cout << "Unkown Exception" << std::endl;}}return 0;
}

1.5 异常的重新抛出

有时catch到一个异常对象后,需要对错误进行分类,其中的某种异常错误需要进行特殊的处理其他错误则重新(throw)抛出异常外层调用链处理。捕获异常后需要重新抛出,直接 throw; 就可以把捕获的对象直接抛出。

#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>using namespace std;// 下面程序模拟展示了聊天时发送消息,发送失败捕获异常
// 可能在电梯地下室等场景手机信号不好,需要多次尝试
// 如果多次尝试都发送不出去,则需要捕获异常再重新抛出
// 如果不是网络差导致的错误,捕获后也要重新抛出class Exception {
public:Exception(const string& errmsg, int id): _errmsg(errmsg), _id(id) {}virtual string what() const {return _errmsg;}int getid() const {return _id;}protected:string _errmsg;int _id;
};class HttpException : public Exception {
public:HttpException(const string& errmsg, int id, const string& type): Exception(errmsg, id), _type(type) {}string what() const override {string str = "HttpException:";str += _type;str += ":";str += _errmsg;return str;}private:const string _type;
};void _SendMsg(const string& s) {if (rand() % 2 == 0) {throw HttpException("网络不稳定,发送失败", 102, "put");}else if (rand() % 7 == 0) {throw HttpException("你已经不是对方的好友,发送失败", 103, "put");}else {cout << "发送成功" << endl;}
}void SendMsg(const string& s) {// 发送消息失败,则再重试3次for (size_t i = 0; i < 4; i++) {try {_SendMsg(s);break;}catch (const Exception& e) {// 捕获异常,如果是102号错误(网络不稳定),则重新发送// 如果不是102号错误,则将异常重新抛出if (e.getid() == 102) {// 重试三次以后还是失败,则说明网络太差,重新抛出异常if (i == 3) {throw;}cout << "开始第" << i + 1 << "次重试" << endl;}else {throw;}}}
}int main() {srand(time(0));string str;while (cin >> str) {try {SendMsg(str);}catch (const Exception& e) {cout << e.what() << endl << endl;}catch (...) {cout << "Unknown Exception" << endl;}}return 0;
}

如果是102号错误,这个异常不处理,出了catch子句,自动析构,再尝试发送。

1.6 异常的安全问题

异常抛出后后面的代码就不再执行,前面申请了资源(内存、锁等),后面进行释放,但是中间可能会抛异常就会导致资源没有释放,这里由于异常就引发了资源泄漏,产生安全性的问题。解决方案:

1. 可以中间捕获异常释放资源后再重新抛出麻烦

2. 后面的智能指针章节讲的RAII方式解决这种问题更方便

其次析构函数中,如果抛出异常也要谨慎处理,比如析构函数要释放10个资源,释放到第5个时抛出异常,则也需要捕获处理,否则后面的5个资源就没释放,也资源泄漏了。《Effective C++》第8个条款也专门讲了这个问题,别让异常逃离析构函数。

1.7 异常的规范

对于用户和编译器而言,预先知道某个程序会不会抛出异常大有裨益,有助于简化代码

C++98中函数参数列表的后面接throw(),表示函数不抛异常,函数参数列表的后面接throw(类型1, 类型2...)表示可能会抛出多种类型的异常,可能会抛出的类型用逗号分割。

C++98的方式这种方式过于复杂,实践中并不好用,C++11中进行了简化函数参数列表后面noexcept表示不会抛出异常

编译器不会在编译时检查noexcept,也就是说如果一个函数noexcept修饰了,但是同时又包含了throw语句或者调用的函数可能会抛出异常编译还是会顺利通过的(有些编译器可能会报个警告)。但是一个声明了noexcept的函数 抛出了异常,程序会调用terminate终止程序

noexcept(expression)还可以作为一个运算符去检测一个表达式 是否会抛出异常可能会则返回false不会就返回true

一般外层处理异常

#include <iostream>
using namespace std;double Divide(int a, int b) // noexcept
{// 当 b == 0 时抛出异常if (b == 0){throw "Division by zero condition!";}return (double)a / (double)b;
}int main()
{try{int len, time;cin >> len >> time;cout << Divide(len, time) << endl;}catch (const char* errmsg){cout << errmsg << endl;}catch (...){cout << "Unknown Exception" << endl;}int i = 0;cout << noexcept(Divide(1, 2)) << endl; // 0cout << noexcept(Divide(1, 0)) << endl; // 0cout << noexcept(++i) << endl; // 1return 0;
}

2、标准库的异常(了解)

exception - C++ Reference

不好用,公司一般自己实现异常库。

http://www.dtcms.com/a/396527.html

相关文章:

  • 网站建设 就业方向江苏省建设人才网站
  • 企业网站app制作价格在线logo制作生成免费
  • 网站制作学校成都住建局官网报名入口
  • 中国建设银行手机银行官方网站免费建设个人网站
  • 长丰网站建设网站建设合同表(书)
  • word怎么做网站链接影院禁止18岁以下观众入内
  • 今天开始学习NGINX服务配置与部署
  • icp备案网站接入信息怎么写高端vi设计机构
  • 江西手机网站建设WordPress明月浩空
  • 网站建设策划案怎么写中上网站建设
  • 物流网站开发系统论文什么网站是做汽车装饰配件的
  • jsp网站开发实例视频服装网站建设项目实施报告
  • wordpress技术站主题装饰工程
  • 设计参考网站有哪些门户网站开发维护合同
  • 探展打卡 Serverless,2025 云栖大会来了
  • 天迈装饰网站建设项目网站开发设计需求文档
  • 重庆网站seo教程帮朋友做网站 知乎
  • 学做ps的网站有哪些app001推广平台官网
  • 餐饮类网站设计地方门户网站备案
  • MySQL 锁 学习笔记
  • 网站备案为何要关站国外主题网站
  • 个人做网站流程百度云做网站
  • 贸易型企业网站建设实验一 html静态网站开发
  • 上海物流公司网站建设青岛网站seo收费标准
  • 手机网站主页设计网站开发图标
  • 旅游微网站建设站长工具高清吗
  • 网站收录和没收录区别不配置iis做网站
  • 湖南旅游网站开发公司网页怎么设计
  • 临沂国际外贸网站建设惠州网站建设方案推广
  • 建立站点的基本步骤长沙企业如何建网站