item14:updating

This commit is contained in:
racaljk 2018-06-12 10:26:32 +08:00
parent d6610da45a
commit 01d49349c5

View File

@ -1,4 +1,17 @@
## Item 14:如果函数不抛出异常请使用noexcept
条款 14:如果函数不抛出异常请使用noexcept
在C++98中异常说明exception specifications是喜怒无常的野兽。你不得不写出函数可能抛出的异常类型如果函数实现有所改变异常说明也可能需要修改。改变异常说明会影响客户端代码因为调用者可能依赖原版本的异常说明。编译器不会为函数实现异常说明和客户端代码中提供一致性保障。大多数程序员最终都认为不值得为C++98的异常说明如此麻烦。
在C++98中异常说明exception specifications是喜怒无常的野兽。你不得不写出函数可能抛出的异常类型如果函数实现有所改变异常说明也可能需要修改。改变异常说明会影响客户端代码因为调用者可能依赖原版本的异常说明。编译器不会为函数实现异常说明和客户端代码中提供一致性保障。大多数程序员最终都认为不值得为C++98的异常说明如此麻烦。
在C++11标准化过程中大家一致认为异常说明真正有用的信息是一个函数是否会抛出异常。非黑即白一个函数可能抛异常或者不会。这种"可能-绝不"的二元论构成了C++11异常说的基础从根本上改变了C++98的异常说明。C++98风格的异常说明也有效但是已经标记为deprecated废弃。在C++11中无条件的**noexcept**保证函数不会抛出任何异常。
关于一个函数是否已经声明为**noexcept**是接口设计的事。函数的异常抛出行为是客户端代码最关心的。调用者可以查看函数是否声明为**noexcept**,这个可以影响到调用代码的异常安全性和效率。
就其本身而言,函数是否为**noexcept**和成员函数是否**const**一样重要。如果知道这个函数不会抛异常就加上**noexcept**是简单天真的接口说明。
不过这里还有给不抛异常的函数加上**noexcept**的动机:它允许编译器生成更好的目标代码。
要想知道为什么了解C++98和C++11指明一个函数不抛异常的方式是很有用了。考虑一个函数**f**,它允许调用者永远不会受到一个异常。两种表达方式如下:
```cpp
int f(int x) throw(); // C++98风格
int f(int x) noexcept; // C++11风格
```