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

C++中noexcept的具体特性及其代码示例

文章目录

        • 1. **作为异常说明符**
        • 2. **作为运算符**
        • 3. **性能优化**
        • 4. **异常安全性**
      • 总结

1. 作为异常说明符

noexcept可以放在函数声明或定义的后面,表示该函数不会抛出任何异常。如果函数在运行时抛出异常,程序会立即终止,并调用std::terminate()函数。

特性:

  • 编译时检查:编译器会检查函数是否可能抛出异常。如果函数内部调用了可能抛出异常的代码,编译器会报错。
  • 运行时终止:如果标记为noexcept的函数在运行时抛出异常,程序会立即终止。

代码示例:

#include <iostream>
#include <stdexcept>void safeFunction() noexcept {// 这个函数不会抛出异常std::cout << "safeFunction called" << std::endl;
}void unsafeFunction() {// 这个函数可能会抛出异常throw std::runtime_error("An error occurred");
}int main() {try {safeFunction();unsafeFunction(); // 这里会抛出异常} catch (const std::exception& e) {std::cerr << "Exception caught: " << e.what() << std::endl;}return 0;
}

输出:

safeFunction called
Exception caught: An error occurred

如果将unsafeFunction标记为noexcept

void unsafeFunction() noexcept {// 这个函数可能会抛出异常throw std::runtime_error("An error occurred");
}

输出:

safeFunction called
terminate called after throwing an instance of 'std::runtime_error'what():  An error occurred

程序会立即终止,并调用std::terminate()

2. 作为运算符

noexcept(expression)用于检查表达式是否可能抛出异常。如果表达式不会抛出异常,则返回true;否则返回false

特性:

  • 编译时检查:编译器会检查表达式是否可能抛出异常。
  • 返回值:返回一个布尔值,表示表达式是否安全。

代码示例:

#include <iostream>
#include <stdexcept>void safeFunction() noexcept {std::cout << "safeFunction called" << std::endl;
}void unsafeFunction() {throw std::runtime_error("An error occurred");
}int main() {std::cout << "safeFunction noexcept: " << noexcept(safeFunction()) << std::endl;std::cout << "unsafeFunction noexcept: " << noexcept(unsafeFunction()) << std::endl;return 0;
}

输出:

safeFunction noexcept: 1
unsafeFunction noexcept: 0
3. 性能优化

标记为noexcept的函数,编译器可以进行一些优化,例如删除异常处理代码、进行函数内联等,从而提高程序的性能。

代码示例:

#include <iostream>
#include <chrono>void safeFunction() noexcept {// 这个函数不会抛出异常std::this_thread::sleep_for(std::chrono::milliseconds(100));
}void unsafeFunction() {// 这个函数可能会抛出异常std::this_thread::sleep_for(std::chrono::milliseconds(100));
}int main() {auto start = std::chrono::high_resolution_clock::now();safeFunction();auto end = std::chrono::high_resolution_clock::now();std::cout << "safeFunction took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << " ms" << std::endl;start = std::chrono::high_resolution_clock::now();unsafeFunction();end = std::chrono::high_resolution_clock::now();std::cout << "unsafeFunction took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << " ms" << std::endl;return 0;
}

输出:

safeFunction took 100 ms
unsafeFunction took 100 ms

虽然在这个简单的例子中性能差异不明显,但在复杂的程序中,noexcept可以显著提高性能。

4. 异常安全性

使用noexcept可以提高代码的异常安全性。标记为noexcept的函数不会抛出异常,因此调用这些函数的代码可以更加自信地使用不带RAII(资源获取即初始化)的代码。

代码示例:

#include <iostream>
#include <vector>class MyClass {
public:MyClass(int value) : value_(value) {}int value() const { return value_; }// 移动构造函数MyClass(MyClass&& other) noexcept : value_(other.value_) {other.value_ = 0;}// 移动赋值运算符MyClass& operator=(MyClass&& other) noexcept {if (this != &other) {value_ = other.value_;other.value_ = 0;}return *this;}private:int value_;
};void testMove() noexcept {std::vector<MyClass> vec;vec.reserve(10);for (int i = 0; i < 10; ++i) {vec.emplace_back(i);}std::vector<MyClass> vec2 = std::move(vec);
}int main() {testMove();return 0;
}

在这个例子中,MyClass的移动构造函数和移动赋值运算符都被标记为noexcept,这使得std::vector在进行内存重新分配等操作时可以安全地使用移动语义。

总结

noexcept是一个非常有用的特性,它可以帮助你编写更安全、更高效的代码。通过标记函数为noexcept,你可以告诉编译器这些函数不会抛出异常,从而让编译器进行优化。同时,noexcept也可以帮助你提高代码的异常安全性,特别是在使用移动语义时。

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

相关文章:

  • 百度文心大模型4.5系列正式开源,同步开放API服务
  • C#跨线程共享变量指南:从静态变量到AsyncLocal的深度解析
  • 网络安全等级保护(等保)全面指南
  • 国产化关系型数据库都有哪些?哪些数据库使用的频次最高?
  • MT-PXle模块【同步电压采集】16bit同步电压输入,最高32路AI
  • 分库分表之实战-sharding-JDBC
  • VLA 论文精读(二十四)ALOHA Unleashed: A Simple Recipe for Robot Dexterity
  • AIGC检测系统升级后的AI内容识别机制与系统性降重策略研究(三阶段降重法)
  • [6-02-01].第05节:配置文件 - YAML配置文件语法
  • 飞纳台式扫描电镜能谱一体机:元素分析与高分辨率成像的完美结合
  • 敏捷开发中的INVEST需求提出原则
  • Python 根据路径解析json数据
  • 高并发限流方案
  • C++ cstring 库解析:C 风格字符串函数
  • Python 数据分析与机器学习入门 (三):Pandas 数据导入与核心操作
  • Java基础(六):数组全面解析
  • RF100:多领域目标检测基准数据集(猫脸码客第284期)
  • 【时时三省】vectorcast使用教程
  • PIXHAWK(ardupilot4.52)上传航点的bug
  • Java-day30-多线程02
  • 大模型——怎么让 AI 写出好看有设计感的网页
  • 链表题解——移除链表元素【LeetCode】
  • 中国电子学会等级考试Python编程真题+答案+解析
  • Spring 依赖注入:官方推荐方式及最佳实践
  • MySQL索引失效场景分析
  • 数据结构笔记5:环形链表的数理分析
  • mysql 小版本升级实战分享
  • 力扣 hot100 Day30
  • 开疆智能CCLinkIE转Canopen网关连接台达伺服驱动器配置案例
  • 自己电脑搭建本地服务器并实现公网访问,内网也能提供互联网连接使用