打代码怎么做网站线上推广平台有哪些
news/
2025/9/22 22:39:57/
文章来源:
打代码怎么做网站,线上推广平台有哪些,北京建站系统模板,如何建设自己的网站来获取流量文章目录 传统的处理错误的方式C异常C异常的使用抛异常的举例异常的重新抛出异常规范 自定义异常体系C标准库中的异常体系异常的优缺点 本篇总结的是C中关于异常的内容
传统的处理错误的方式
在C语言中#xff0c;对于传统的错误方式有
终止程序#xff1a;例如assert异常C异常的使用抛异常的举例异常的重新抛出异常规范 自定义异常体系C标准库中的异常体系异常的优缺点 本篇总结的是C中关于异常的内容
传统的处理错误的方式
在C语言中对于传统的错误方式有
终止程序例如assert但是问题在于有些过于暴力了直接会终止程序返回错误码检查错误不太方便需要去查找错误成本比较高
C异常
因此针对这种情况C新增了异常的概念异常是一种处理错误的方式当一个函数发现自己无法处理的错误的时候就可以抛出异常让函数直接或间接的让调用者来处理这个错误
throw当问题出现的时候会抛出异常这是throw关键字来表示的catch当有需要处理的问题时catch用于捕获这个异常可以有多个catch进行捕获trytry当中的代码标识将被激活的特定异常在它的后面会跟着catch用于异常捕获
C异常的使用
抛出和匹配原则
异常是抛出对象抛出的因此这个对象的类型决定了要如何catch这个异常被选中的处理代码是调用链中的与该对象匹配且离异常位置最近的那个抛出异常对象后会生成一个异常对象的拷贝因为抛出的异常对象可能是一个临时对象所以会生成一个拷贝对象这个拷贝的临时对象会在catch后销毁有些类似于传值返回实际中的抛出和捕获也有例外比如抛出派生类对象可以用基类捕获多态的原理
在函数调用链中异常栈展开匹配原则
首先检查throw本身是否在try块内部如果是再查找匹配的catch语句。如果有匹配的则调到catch的地方进行处理没有匹配的catch则退出当前函数栈继续在调用函数的栈中进行查找匹配的catch如果到达main函数的栈依旧没有匹配的则终止程序。上述这个沿着调用链查找匹配的catch子句的过程称为栈展开。所以实际中我们最后都要加一个catch(...)捕获任意类型的异常否则当有异常没捕获程序就会直接终止找到匹配的catch子句并处理以后会继续沿着catch子句后面继续执行
抛异常的举例
void div1(int x, int y)
{if (y 0){throw 除0错误;}else{cout x / (double)y endl;}
}int main()
{int x 0, y 0;cin x y;try{div1(x, y);}catch(const char* str){cout str endl;}return 0;
}异常的重新抛出
在实际的使用中可能会遇到单个的catch不能处理一个异常需要把这个异常再次进行抛出所以catch是可以重新抛出给更上层的函数的
举个例子比如下面的场景
void div1(int x, int y)
{int* p new int[10];if (y 0){throw 除0错误;}else{cout x / (double)y endl;delete[] p;cout delete[] endl;}
}如果只是这样单纯的抛异常那么对于p所指向的这段空间就得不到释放在实际的开发中这种内存泄漏是十分严重的情景因此处于这种原因可以在重新抛出异常
double Division(int a, int b)
{// 当b 0时抛出异常if (b 0){throw Division by zero condition!;}return (double)a / (double)b;
}
void Func()
{int* array new int[10];try {int len, time;cin len time;cout Division(len, time) endl;}catch (...){cout delete [] array endl;delete[] array;throw;}// ...cout delete [] array endl;delete[] array;
}
int main()
{try{Func();}catch (const char* errmsg){cout errmsg endl;}return 0;
}这样无论在什么情况下都可以既能释放内存又能保证异常正常的抛出和接收了
异常规范
异常规格说明的目的是为了让函数使用者知道该函数可能抛出的异常有哪些可以在函数的后面加一个throw(类型)来说明这个函数可能抛出的所有异常类型如果只是加一个throw则表示函数不抛异常若没有无异常接口声明则此函数可以抛任何类型的异常
自定义异常体系
在实际的开发过程中异常体系是需要被自定义出来的因此会提前定义一套继承的规范体系抛出的都是继承的派生类对象只需要捕获一个基类就可以了 // 服务器开发中通常使用的异常继承体系
// 定义了一个异常基类
class Exception
{
public:Exception(const string errmsg, int id):_errmsg(errmsg), _id(id){}// 可以在外部显示的查看错误信息是什么virtual string what() const{return _errmsg;}
protected:// 通常包括有异常信息和抛出异常所对应的id号码string _errmsg;int _id;
};// 由基类异常继承而来的数据库异常
class SqlException : public Exception
{
public:SqlException(const string errmsg, int id, const string sql):Exception(errmsg, id), _sql(sql){}// 对基类中的输出信息进行对应的改造使得输出对应的错误信息virtual string what() const{string str SqlException:;str _errmsg;str -;str _sql;return str;}
private:// 在数据库异常中新增了和数据库有关的信息const string _sql;
};// 缓存区异常
class CacheException : public Exception
{
public:CacheException(const string errmsg, int id):Exception(errmsg, id){}virtual string what() const{string str CacheException:;str _errmsg;return str;}
};// web服务器异常
class HttpServerException : public Exception
{
public:HttpServerException(const string errmsg, int id, const string type):Exception(errmsg, id), _type(type){}virtual string what() const{string str HttpServerException:;str _type;str :;str _errmsg;return str;}
private:const string _type;
};// 模拟数据库中的命令
void SQLMgr()
{srand(time(0));if (rand() % 7 0){throw SqlException(权限不足, 100, select * from name 张三);}
}void CacheMgr()
{srand(time(0));if (rand() % 5 0){throw CacheException(权限不足, 100);}else if (rand() % 6 0){throw CacheException(数据不存在, 101);}SQLMgr();
}void HttpServer()
{srand(time(0));if (rand() % 3 0){throw HttpServerException(请求资源不存在, 100, get);}else if (rand() % 4 0){throw HttpServerException(权限不足, 101, post);}CacheMgr();
}int main()
{while (1){this_thread::sleep_for(chrono::seconds(1));try {HttpServer();}catch (const Exception e){cout e.what() endl;}catch (...){cout Unkown Exception endl;}}return 0;
}这样就能把错误信息统一的放置到一个日志中方便进行查看哪部分内容可能会出现错误
C标准库中的异常体系 异常的优缺点
优点
异常对象定义好了相比错误码的方式可以清晰准确的展示出错误的各种信息甚至可以包含堆栈调用的信息这样可以帮助更好的定位程序的bug返回错误码的传统方式有个很大的问题就是在函数调用链中深层的函数返回了错误那么我们得层层返回错误最外层才能拿到错误很多的第三方库都包含异常比如boost、gtest、gmock等等常用的库那么我们使用它们也需要使用异常部分函数使用异常更好处理比如构造函数没有返回值不方便使用错误码方式处理。比如T operator这样的函数如果pos越界了只能使用异常或者终止程序处理没办法通过返回值表示错误
缺点
异常会导致程序的执行流乱跳并且非常的混乱并且是运行时出错抛异常就会乱跳。这会导致我们跟踪调试时以及分析程序时比较困难异常会有一些性能的开销。当然在现代硬件速度很快的情况下这个影响基本忽略不计C没有垃圾回收机制资源需要自己管理。有了异常非常容易导致内存泄漏、死锁等异常安全问题。这个需要使用RAII来处理资源的管理问题。学习成本较高C标准库的异常体系定义得不好导致大家各自定义各自的异常体系非常的混乱异常尽量规范使用否则后果不堪设想随意抛异常外层捕获的用户苦不堪言。所以异常规范有两点一、抛出异常类型都继承自一个基类。二、函数是否抛异常、抛什么异常都使用func throw();的方式规范化
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/910619.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!