C++ Primer 5th笔记(chap 18 大型程序工具)noexcept

2024-03-28 08:38

本文主要是介绍C++ Primer 5th笔记(chap 18 大型程序工具)noexcept,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 通过提供 noexcept 说明 ( noexcept specification ) 指定某个函数不会抛出异常。 其形式是关键字 noexcept 紧跟在函数的参数列表后面

{// 紧跟在函数的参数列表后面// 该说明应该在函数的尾置返回类型之前// 在成员函数中,noexcept说明符应该出现在const以及引用限定之后// 而在final,override,或者虚函数的=0之前。void recoup(int) noexcept;//不会抛出异常void alloc(int);//可能会抛出异常//noexcept要么出现在该函数的所有声明和定义语句中//要么一次也不出现。//我们也可以在函数指针的声明和定义中指定noexcept//在typedef或类型别名中不能出现noexcept
}

对于一个函数来说, noexcept 说明要么出现在该函数的所有声明语句和定义语句中, 要么一次也不出现。

  • 该说明应该在函数的尾置返回类型之前。

  • 也可以在函数指针的声明和定义中指定 noexcept。

  • 在 typedef 或类型别名中则不能出现 noexcept。

  • 在成员函数中, noexcept 说明符需要跟在 const 及引用限定符之后, 而在 final、 override 或虚函数的=0 之前

1.1 违反异常说明

编译器并不会在编译时检查noexcept说明。如果在一个函数中说明了noexcept的同时又含有throw语句,或者调用可能抛出异常的其他函数,编译器将会顺序编译通过,并不会因为这种违反异常说明滚的情况而报错。(又可能会有编译器会提出警告)

// 尽管该函教明显违反了异常说明, 但它仍然可以顺利编译通过
void f ( ) noexcept //承诺不会抛出异常
{throw exception ( ); / / 违反了异常说明
}

因此可能会出现一个函数既声明了不会抛出异常,而又抛出了异常。此时,一旦抛出异常,程序就会调用terminate以确保遵守不在运行时抛出异常的承诺。上述过程对是否执行栈展开没有约定。
因此noexcept用在两种情况。

  • 我们确认函数不会抛出异常
  • 我们根本不会处理该异常

1.2 异常说明的实参

noexcept 说明符接受一个可选的实参, 该实参必须能转换为 bool 类型: 如果实参是 true, 则函数不会抛出异常; 如果实参是 false, 则函数可能抛出异常:

void recoup (int) noexcept (true); / / recoup 不会抛出异常
void alloc (int ) noexcept ( false);/ / alloc 可能抛出异常

1.3 noexcept 运算符 (noexcept operator)

noexcept 运算符是一个一元运算符, 它的返回值是一个 bool 类型的右值常量表达式,用于表示给定的表达式是否会抛出异常
和sizeof一样,noexcept也不会对该表达式求值。

eg. noexcept (recoup (i) ) // 如果 recoup 不抛出异常则结果为 true; 否则结果为 falsenoexcept (e)
当 e 调用的所有函数都做了不抛出说明且 e 本身不含有 throw 语句时, 上述表达式为
true; 否贝lj noexcept (e> 返回 falsevoid f ( ) noexcept (noexcept (g ( > ) ); //f 和 g 的异常说明一致
如果函数 g 承诺了不会抛出异常, 则 f 也不会抛出异常; 如果 g 没有异常说明符, 或者 g
虽然有异常说明符但是允许抛出异常, 则 f 也可能抛出异常

1.4 异常说明与指针、 虚函数和拷贝控制

1.4.1 指针

函数指针及该指针所指的函数必须具有一致的异常说明。

  • 如果我们为某个指针做了不抛出异常的声明, 则该指针将只能指向不抛出异常的函数。
  • 如果我们显式或隐式地说明了指针可能抛出异常, 则该指针可以指向任何函数, 即使是承诺了不抛出
    异常的函数也可以
// recoup和pf1都承诺不会抛出异常
// alloc可能会抛出错误
void (*pf)(int) noexcept = recoup;
void (*pf2)(int) = recoup;//正确
pf = alloc;//错误,
pf2 = alloc;//正确

1.4.2 虚函数

如果一个虚函数承诺了它不会抛出异常,则它后续的派生类的虚函数也必须做出同样的承诺。
如果基类的虚函数允许抛出异常时,我们可以设置派生类对应的函数不能抛出异常,当然也可以是允许抛出异常

class Base {
public:virtual double f1(double) noexcept;// 显式和隐式地指出可能会抛出异常virtual int f2() noexcept(false);virtual void f3();
};class D : public Base {
public:double f1(double);//错误,没有指明是noexceptint f2() noexcept(true);//正确,虽然基类的是可能抛出异常的void f3() noexcept;//正确,同上
};

1.4.3 拷贝控制成员

  • 当编译器合成拷贝控制成员时,同时也生成一个异常说明符。
  • 如果对所有成员和基类的所有操作都承诺了不会抛出异常,则合成的成员是noexcept的。
  • 如果合成成员调用的任意一个函数可能会抛出异常,则合成的成员是noexcept(false)的。
    -我们定义了一个析构函数,但是没有为它提供异常说明,编译器将会合成一个,合成的异常说明符将与假设编译器为类合成的析构函数时所得的异常说明一致。

这篇关于C++ Primer 5th笔记(chap 18 大型程序工具)noexcept的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/855069

相关文章

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

C++ STL-string类底层实现过程

《C++STL-string类底层实现过程》本文实现了一个简易的string类,涵盖动态数组存储、深拷贝机制、迭代器支持、容量调整、字符串修改、运算符重载等功能,模拟标准string核心特性,重点强... 目录实现框架一、默认成员函数1.默认构造函数2.构造函数3.拷贝构造函数(重点)4.赋值运算符重载函数

C++ vector越界问题的完整解决方案

《C++vector越界问题的完整解决方案》在C++开发中,std::vector作为最常用的动态数组容器,其便捷性与性能优势使其成为处理可变长度数据的首选,然而,数组越界访问始终是威胁程序稳定性的... 目录引言一、vector越界的底层原理与危害1.1 越界访问的本质原因1.2 越界访问的实际危害二、基

基于Python编写自动化邮件发送程序(进阶版)

《基于Python编写自动化邮件发送程序(进阶版)》在数字化时代,自动化邮件发送功能已成为企业和个人提升工作效率的重要工具,本文将使用Python编写一个简单的自动化邮件发送程序,希望对大家有所帮助... 目录理解SMTP协议基础配置开发环境构建邮件发送函数核心逻辑实现完整发送流程添加附件支持功能实现htm

C#控制台程序同步调用WebApi实现方式

《C#控制台程序同步调用WebApi实现方式》控制台程序作为Job时,需同步调用WebApi以确保获取返回结果后执行后续操作,否则会引发TaskCanceledException异常,同步处理可避免异... 目录同步调用WebApi方法Cls001类里面的写法总结控制台程序一般当作Job使用,有时候需要控制

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

MySQL慢查询工具的使用小结

《MySQL慢查询工具的使用小结》使用MySQL的慢查询工具可以帮助开发者识别和优化性能不佳的SQL查询,本文就来介绍一下MySQL的慢查询工具,具有一定的参考价值,感兴趣的可以了解一下... 目录一、启用慢查询日志1.1 编辑mysql配置文件1.2 重启MySQL服务二、配置动态参数(可选)三、分析慢查

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c

C++归并排序代码实现示例代码

《C++归并排序代码实现示例代码》归并排序将待排序数组分成两个子数组,分别对这两个子数组进行排序,然后将排序好的子数组合并,得到排序后的数组,:本文主要介绍C++归并排序代码实现的相关资料,需要的... 目录1 算法核心思想2 代码实现3 算法时间复杂度1 算法核心思想归并排序是一种高效的排序方式,需要用