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

企业做宣传网站多少钱教育类型网站

企业做宣传网站多少钱,教育类型网站,wordpress主题图片路径设置,手机网站源码最好我们知道,C语言处理错误的方式:返回错误码,缺陷:需要程序员自己查找错误信息。终止程序(如assert),缺陷:用户难以接受。一、 异常的概念由于C语言中处理错误的方式不够理想和方便,C推…

我们知道,C语言处理错误的方式:

  1. 返回错误码,缺陷:需要程序员自己查找错误信息。
  2. 终止程序(如assert),缺陷:用户难以接受。

一、 异常的概念

由于C语言中处理错误的方式不够理想和方便,C++推出了自己处理错误的方式——异常。当一个函数遇到无法处理的错误时,会抛出异常,让函数的调用者来处理。

二、 异常的定义

先看看以下代码:

void func()
{throw "error";
}void test()
{try{func();}catch (const char* str){cout << str << endl;}catch (...){cout << "未知异常" << endl;}
}

注意:

  1. try语句可以和多条catch语句连接,这样子可以捕获不同类型的异常
  2. 异常与对应类型的catch相匹配
  3. catch(...)可用于捕获任意类型的异常 ,防止未知的异常导致程序出错终止

三、异常的使用

1.异常的栈展开匹配

#include<iostream>
using namespace std;
double Division(int len, int times)
{if (times == 0){throw"除零错误";}else{return (double)len / times;}
}
void func()
{throw 1;
}
void Func()
{try{int len, times;cin >> len >> times;cout << Division(len, times) << endl;func();}catch (const char* str){cout << str << endl;}}
int main()
{try{Func();}catch (const char* str){cout << str << endl;}catch (...){cout << "未知异常" << endl;}return 0;
}

这里顺序是这样的,

  1. 先检查throw是否在try语句块中,如果在,则匹配相应的catch语句。
  2. 如果匹配不到或者不在try语句中,则推出当前函数栈,继续在调用函数的栈中进行查找匹配的catch语句。
  3. 如果到达main函数的栈,还是没有找到与之匹配的catch则会终止程序
  4. 如果匹配得到相应的catch语句并处理后,会继续执行catch后面的语句

值得注意的是:

在异常被抛出时,会创建一个异常对象的拷贝或移动,这个拷贝或移动的结果,是用于调用栈里向上传递的,直到找到于之匹配的catch语句块,这是为了保证抛出后,原始对象的状态的改变不会影响已经抛出的异常

在C++中抛出异常时,会创建一个异常对象的拷贝或者移动,以此来确保异常对象在抛出点和捕获点之间的生命周期和安全性。在C++11以后的版本中,如果异常类型支持移动语义并且操作是高效的,那么编译器偏向于使用移动构造来抛出异常。

2.异常的重新抛出

有时候我们可能发现在catch后不立即处理异常,而是选择重新抛出(rethrow)它,以便于让上层代码有机会处理它

在C++中,异常处理通常通过try-catch块实现。某些情况下,当前代码可能需要记录或部分处理异常,但仍希望上层调用者能够捕获并进一步处理。此时可以通过重新抛出(rethrow)实现。

try {// 可能抛出异常的代码
} catch (const std::exception& e) {// 记录异常信息std::cerr << "Log: " << e.what() << std::endl;// 重新抛出throw;
}

实际应用场景:

1.资源清理后重新抛出:

void processFile() {std::ifstream file("data.txt");try {if (!file) throw std::runtime_error("File open failed");// 处理文件内容} catch (...) {file.close(); // 确保资源释放throw; // 重新抛出异常}
}

在这个场景里可能因为抛异常导致不能让资源释放,所以现在catch语句里先释放空间,再将异常重新抛出。

异常重新抛出时,不会创建一个新的异常对象的拷贝或移动,而是继续传播当前捕获的异常对象

这个过程是高效的,因为它避免了不必要的对象的拷贝或移动,然而,这个也意味着在catch块中修改捕获的异常对象的状态可能会影响到上层代码对于这个对象的处理,因为它们是同一个对象,因此在重新抛出异常前,通常不建议修改捕获的异常对象的状态。

注意事项

  • 重新抛出的异常会保留原始异常类型和调用栈信息。
  • throw;只能在catch块中使用,否则会导致std::terminate
  • 若需要修改异常类型(如场景2),需显式抛出新异常而非使用throw;

2.异常安全

C++中异常会频繁导致资源泄漏的问题,比如在new和delete中间抛出来了异常,导致内存泄漏,在lock和unlock之间抛出异常导致死锁,C++通常使用RAII  来解决上面的问题(智能指针章节会讲到)

3.异常规范

//这个表示这个函数会抛出A/B/C/D中的某种类型
void func() throw(A,B,C,D);
//这个表示这个函数指挥抛出bad_allow的异常
void* operator new(std::size_t size) throw(std::bad_allow)
//这个表示不会抛出异常
void&operator delete (std::size_t size,void*ptr) throw();//C++11中新增的noexcept表示不后悔抛出异常
thread() noexcept;
thread(thread&& x) noexcept; 

四、自定义异常体系

实际上,异常的抛出和捕获,在某种情况下不需要类型一一对应,那就是抛出派生对象,用基类来捕获(在实际中非常好用的做法)

#include <iostream>
#include <exception>
#include <string>// 基类异常
class BaseException : public std::exception {
public:virtual const char* what() const noexcept override {return "BaseException occurred";}
};// 派生类异常1
class DerivedExceptionA : public BaseException {
public:const char* what() const noexcept override {return "DerivedExceptionA occurred";}
};// 派生类异常2
class DerivedExceptionB : public BaseException {
public:const char* what() const noexcept override {return "DerivedExceptionB occurred";}
};void riskyFunction(int type) {if (type == 1) {throw DerivedExceptionA();}else if (type == 2) {throw DerivedExceptionB();}
}int main() {try {riskyFunction(1);  // 测试派生类A// riskyFunction(2);  // 测试派生类B}catch (const BaseException& e) {  // 基类捕获所有派生类异常std::cerr << "Caught exception: " << e.what() << std::endl;}return 0;
}

用基类引用统一捕获不同的派生类对象,实现多态,规范了异常体系,防止乱抛异常导致项目程序终止。

五、标准库异常

C++标准库定义了一套异常类体系,均派生自std::exception基类,用于处理程序运行时的错误。这些异常类覆盖了常见错误场景,如内存分配失败、逻辑错误、范围越界等。

  1. std::exception
    所有标准库异常的基类,提供虚成员函数what()返回错误描述。

    try { /* 可能抛出异常的代码 */ } 
    catch (const std::exception& e) {std::cerr << "Error: " << e.what() << std::endl;
    }
  2. std::runtime_error
    表示程序运行时才能检测的错误(如文件打开失败)。
    派生类包括:

  3. std::logic_error
    表示程序逻辑错误(如无效参数)。
    派生类包括:

    ps:operator[]不会做边界检查,如果你尝试访问一个越界的索引,operator[]会返回对应位置的引用,但是这是一个未定义的行为,可能会导致程序崩溃或其他不可预测的结果。

  4. std::bad_alloc
    内存分配失败时由new抛出。

    try { int* arr = new int[1000000000000]; } 
    catch (const std::bad_alloc& e) {std::cerr << "Memory allocation failed: " << e.what() << std::endl;
    }
  5. std::bad_cast
    dynamic_cast对引用类型转换失败时抛出。

PS:C++标准异常库设计的不够好用,实际上很多公司都是自定义一套异常体系


自定义异常类

可通过继承std::exception或其派生类实现自定义异常:

class MyException : public std::runtime_error {
public:MyException(const std::string& msg) : std::runtime_error(msg) {}
};try { throw MyException("Custom error"); } 
catch (const MyException& e) {std::cerr << e.what() << std::endl;
}


异常安全实践

  • RAII原则:通过智能指针(如std::unique_ptr)管理资源,避免内存泄漏。
  • noexcept规范:对不抛出异常的函数标记noexcept以优化性能。
  • 避免异常滥用:仅对异常情况使用异常(如关键错误),而非控制流程。

异常与性能

异常处理可能引入额外开销,但在现代编译器中,若无异常抛出,性能影响可忽略。建议在错误处理复杂或跨多层函数调用时使用异常。

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

相关文章:

  • 有哪些可以做头像的网站购物网页代码
  • 黄江镇网站仿做动易 网站统计 首次打开
  • 深圳自适应网站建设价格音乐网站开发分享
  • 做网站在哪个程序做国内疫苗接种率
  • 广西南宁网站策划中国建设银行官网查询
  • 高中信息技术网站设计规划济南网站排名推广
  • 手机网站开发常用工具五金技术支持东莞网站建设
  • 建设企业网站内容龙岗网站的建设
  • 南通哪些公司做网站用电脑做网站的历史在哪里找
  • 网站建设 技术 哪些内容顶易云外贸软件
  • 做网站前产品经理要了解什么德州市建设局网站
  • 网站关键词搜不到怎么给产品做网络推广
  • 视频网站的防盗链是怎么做的免费绘画素材网站
  • 网站怎么添加滤镜功能吗移动网络
  • 上传下载网站模板美容美发网站模板
  • 手机特殊网站做网站guangxiyanda
  • 网站建设调查内容有哪些宁波建设监理协会
  • 帕兰映像 wordpress整站优化
  • 珠海网站设计平台莱芜关于网站建设的公司
  • 企业网站怎么做的更好温州网站开发流程
  • 企业信息型网站有哪些网站建设的基本原则
  • php+网站开发+pdf电力建设监理招聘网站
  • 什么叫网站域名wordpress默认排序
  • 建设网站的法律可行性工业企业解决方案
  • 济宁建站公司深圳做网站专业的公司
  • 做网站建立数据库网站保持排名
  • 学校网站建设团队网站建设添加音乐的代码
  • 做外贸生意用哪个网站wordpress 数据库 插件
  • 江永网站建设wordpress怎么还原
  • 信息技术做网站厦门建设网站企业