More Effective C++ Item14:明智运用exception specifications

使用exception specifications你必须非常仔细去确保,函数调用的子函数、注册的回调函数不会违背约定。而设计模板内部的异常更难确保。

设计回调机制的时候,如果调用方规定了不抛出异常,就必须确保注册进来的函数均不会抛出异常,书上给出了这样的做法:

typedef void(*CallBackPtr)(
    int eventXLocation,
    int eventYLocation,
    void *dataToPassBack
    ) throw();

并以CallBackPtr类型注册函数。SM大大自己也提到,标准不允许typedef内出现exception specifications,而这是许多编译器心照不宣的做法。

VC++的做法是这样的:VC++有这样一个extended attribute syntax叫做__declspec,声明函数时加上__declspec(nothrow)就可以有和throw()一样的效果了。MSDN上给的例子https://msdn.microsoft.com/en-us/library/49147z04.aspx:

#define WINAPI __declspec(nothrow) __stdcall

并指出对于大量声明函数很方便。

编译器并不为exception specifications负责!最多给个警告,剩下就都是运行时的事情了。

运行时抛出不在exception specifications之列的异常会调用unexpected函数,条款14推荐的做法之一是利用set_unexpected重定义unexpected,抛出一个自定的“未知异常”,并在所有的exception specifications加入这个东西。但是亲测VS2015的set_unexpected并不会正确表现。

另一个做法就是将新的unexpected函数写为直接throw;出去,这样会转而抛出std::bad_exception,再将这个列入exception specifications即可。而这样高层也许做了很多准备迎接异常也会被底层的“好意”而浪费,这需要的就是工程上的统一了。

时间: 2024-10-09 21:25:13

More Effective C++ Item14:明智运用exception specifications的相关文章

More Effective C++ 条款14 明智运用exception specifications

1. Exception specifications作为函数声明的一部分,用于指出(并不能限制)函数可能会抛出的异常函数.C++规定,一个拥有exception specification的函数指针只能被赋予一个有着相同或更为局限的exception specification的函数地址,因而编译器要保证"在函数指针传递之际检验exception specifications".(但visual studio 2013不支持此项要求) 2. 当函数抛出exception specif

More Effective C++----(14)审慎使用异常规格(exception specifications)

Item M14:审慎使用异常规格(exception specifications) 毫无疑问,异常规格是一个引人注目的特性.它使得代码更容易理解,因为它明确地描述了一个函数可以抛出什么样的异常.但是它不只是一个有趣的注释.编译器在编译时有时能够检测到异常规格的不一致.而且如果一个函数抛出一个不在异常规格范围里的异常,系统在运行时能够检测出这个错误,然后一个特殊函数unexpected将被自动地调用.异常规格既可以做为一个指导性文档同时也是异常使用的强制约束机制,它好像有着很诱人的外表. 不过

VisualC++ Exception Specifications

Exception Specifications这个词我成为"异常规格",不知道是否准确,有更准确的希望大家布林刺激哦. 异常规格被用于指出一个函数能抛出什么样的异常. 函数可以抛出任何类型异常 void MyFunction(int i) throw(...); 函数不能抛出异常 void MyFunction(int i) throw(); 其等效于 void __declspec(nothrow) MyFunction(int i) throw(); VisualC++与标准C+

C++学习书籍推荐《More Effective C++》下载

百度云及其他网盘下载地址:点我 编辑推荐 <More Effective C++:35个改善编程与设计的有效方法(中文版)>:传世经典书丛 媒体推荐 <Effective c++>(Scott Meyers第一本书)的荣耀:"对于任何渴望在中阶或高阶层面精通c++的人,我慎重推荐<Effective c++>," --(The C/C++User's Journal) 作者简介 作者:(美国)梅耶(Scott Meyers) 译者:侯捷 Scott

《More Effective C++》读书笔记

http://www.cnblogs.com/tianyajuanke/archive/2012/11/29/2795131.html 一.基础议题(Basics) 1.仔细区别 pointers 和 references 当一定会指向某个对象,且不会改变指向时,就应该选择 references,其它任何时候,应该选择 pointers. 实现某一些操作符的时候,操作符由于语义要求使得指针不可行,这时就使用引用. 二者之间的区别是:在任何情况下都不能用指向空值的引用,而指针则可以:指针可以被重新

Effective C++读书笔记(转)

第一部分 让自己习惯C++ 条款01:视C++为一个语言联邦 一.要点 ■ c++高效编程守则视状况而变化,取决于你使用c++的哪一部分. 二.扩展 将c++视为一个由相关语言组成的联邦而非单一语言会帮助你更好的理解,其由c.object-oriented c++.template c++和stl四部分组成. 条款02:尽量以const,enum,inline替换#defines 一.要点 ■ 对于单纯变量,最好以const对象或enums替换#defines. ■ 对于形似函数的宏,最好改用i

More Effective C++ 条款35 让自己习惯于标准C++ 语言

(由于本书出版于1996年,因此当时的新特性现在来说可能已经习以为常,但现在重新了解反而会起到了解C++变迁的作用) 1. 1990年后C++的重要改变 1). 增加了新的语言特性:RTTI,namespaces,bool,关键词mutable和explicit,enums作为重载函数之自变量所引发的类型晋升转换,以及"在class 定义区内直接为整数型(intergral) const static class members设定初值"的能力. 2). 扩充了Templates的特性

More Effective C++ (2)

接下来的是more effective c++ 11至20条款: 11.禁止异常信息(exceptions)传递到析构函数外.析构函数的调用情况可能有两种:(1)对象正常销毁 (2)异常传播过程中的栈展开机制-销毁.如果在析构函数内抛出异常,它不会被析构函数捕获,它会传播到析构函数的调用端,如果调用端是因为其他异常而被调用的,那么程序就会死掉.还有可能就是导致后面的语句无法执行,所以不能让异常传播到析构函数之外. 12.理解“抛出一个异常”与“传递一个参数”或“调用一个虚函数”间的差异.(1)抛

More Effective C++

条款一:指针与引用的区别 指针与引用看上去完全不同(指针用操作符'*'和'->',引用使用操作符'.'),但是它们似乎有相同的功能.指针与引用都是让你间接引用其他对象.你如何决定在什么时候使用指针,在什么时候使用引用呢? 首先,要认识到在任何情况下都不能用指向空值的引用.一个引用必须总是指向某些对象.因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量.相反,如果变量肯定指向一个对象,例如你的设计不允许变量为