`

Item 8 异常安全的ctor和dtor

阅读更多

根据下面的声明,写出实现的代码,要求达到异常安全或异常中立。这意味着即使发生了异常,Stack对象也要处于正确统一的状态。异常要被传递给调用者,让调用者根据上下文处理异常。

请思考下面的问题:
● 异常安全的级别有哪些?
● 通用容器是否可以做到“异常中立”(exception neutral)?
● STL里的容器是异常安全,还是异常中立?
● 异常安全是否会影响容器的接口设计?
● 通用容器是否应该有异常列表?

上面的ctor是异常安全还是异常中立?
假设任意函数都可以抛出异常,那么先要知道都调用了哪些函数。new T[vsize_] 这句先调用了operator new[]()(全局或T的成员函数)申请内存,然后调用vsize_个T的ctor来初始化这些对象。
1> operator new[]()失败时会抛出bad_alloc异常;
2> T的ctor也可以抛出异常,然后系统自动调用dtor把前面构造成功的对象都销毁,最后回收所有内存。
3> 在dtor销毁对象时如果抛出异常,那么系统直接调用terminate中止整个应用程序的执行,更干净。
所以,Stack::Stack()既是异常安全也是异常中立。
1> 如果抛出了bad_alloc异常,则该异常被传递到调用者那里,而没有被本地捕获。这就做到了异常中立。
2> 无论何种异常,最后内存都被回收。这就做到了资源无泄漏。
3> 对象状态能在异常前后保持正确。vsize_虽然被赋值,但是因为对象最后都被销毁了,所以相当于不存在错误对象。

这样写和上面没什么区别。

再看dtor的实现:

那句delete实际上调用了T::~T()和operator delete[]()。后者因为声明的关系不抛出异常:
void operator delete[]( void* ) throw();
void operator delete[]( void*, size_t ) throw();
如果有人重载了它们而抛出了异常,则认为它们犯错!
~T()可能抛出异常,但Stack要求它不抛出。否则,让dtor做到完全的异常安全是不可能的。
换言之,一个类的dtor如果允许抛出异常,那么该类不可能正常工作!保证异常不离开dtor是很重要的。如果你习惯上给每个dtor后面都加上throw(),没问题。这说明你重视这方面。

分享到:
评论

相关推荐

    Exceptional C++ 47个疑难问题详解 PDF格式

    5. **构造与析构(Ctor & Dtor)**:理解构造函数和析构函数的工作原理是C++对象生命周期管理的关键。书中可能讨论构造链、虚析构函数、资源获取即初始化(RAII)原则等。 6. **多态(Polymorphism)**:C++的多态包括...

    Arena分配器,DTOR和嵌入式预分配缓冲区

    《Arena分配器,DTOR和嵌入式预分配缓冲区》 在软件开发中,内存管理是至关重要的一环,尤其在C++编程中,合理的内存管理可以极大地提高程序的性能和稳定性。本主题将深入探讨“Arena分配器”、“析构函数(DTOR)”...

    全局对象构造与析构机制剖析

    - **.ctor** 和 **.dtor**:`.ctor`段存储了需要在程序初始化阶段调用的构造函数地址,而`.dtor`段则存储了需要在程序终止阶段调用的析构函数地址。GCC会在编译过程中自动为全局对象生成相应的构造和析构函数调用,...

    Eclipse Juno+mingw+wxWidgets

    最后,选择Miscellaneous,在other flags中输入-c -Wundef -Wno-ctor-dtor-privacy-fno-strict-aliasing。 wxWidgets库文件配置 在Eclipse中,需要配置wxWidgets的库文件。在MinGW C++ Linker->Libraries中,按照...

    数进制转换代码

    首先,我们从最基础的开始,十进制是我们日常生活中最常用的计数系统,它基于10个数字:0, 1, 2, 3, 4, 5, 6, 7, 8和9。而二进制则只有两个数字:0和1,它是计算机内部表示数据的基础,因为所有电子设备的开关状态都...

    Delphi面向对象编程思想

    这两个函数分别以构造函数前缀`ctor`和析构函数前缀`dtor`标识。 6. 异常处理:Delphi支持异常处理机制,通过try-finally和try-except语句块可以捕获和处理运行时错误。这有助于编写健壮的代码,确保即使在发生错误...

    adams驱动函数

    常用的常数函数包括 PI(圆周率)、RTOD(弧度转化为度数时的乘积系数)、DTOR(度数转化为弧度时的乘积系数)。 2. 运动副的驱动函数:运动副的驱动函数用于描述运动副的运动规律。常用的运动副驱动函数包括 ...

    wxwidgets配置

    3. **设置Miscellaneous选项**:在Miscellaneous部分,增加Other flags,例如`-c -Wundef -Wno-ctor-dtor-privacy -fno-strict-aliasing -mthreads –mwindows`。这些标志有助于提高代码质量,同时确保与wxWidgets库...

    C#软件开发规范经典

    4. Ctor, Init, Dtor:构造函数、初始化方法和析构函数在这里声明。窗体类的特定事件处理方法也应在此定义。 5. Method:主要的对外接口方法(如Open, Close等)在此处声明,这些方法代表类的核心功能。 6. Function...

    C++- THE GOOD, BAD, AND UGLY.pdf

    构造函数(ctor)和析构函数(dtor)是C++类对象生命周期中的重要概念。构造函数用于初始化类对象的所有成员变量,而析构函数则用于清理对象拥有的任何资源,比如动态分配的内存。在C++中,“this”指针是一个指向...

    gcc C语言API

    GCC C语言API中的函数和类在设计时考虑到了异常中立性,即这些组件可以在存在异常的情况下正常工作,不会因为异常而影响到程序的整体稳定性。 #### 七、GCC C语言API的调试支持 ##### 7.1 使用g++编译器 GCC ...

    用c实现面向对象(oopc)

    系统和全面地介绍用c的方式实现面向对象编程。包括继承,虚函数,异常等处理 来自法国的牛人,采用宏的方式实现,形式如下: void constMethodDecl(print) { printf("name:\t%s\n", this->m.name); } ...

    libshelf:elf文件格式的实用程序

    函数挂钩/重定向的几种形式,包括plt注入,DT_DEBUG到DT_NEEDED转换,函数蹦床和.ctor / .dtor覆盖。 提供类似于shell的界面,用于检查和修改ELF二进制文件。 将提供对ELF文件中任何数据结构的完全读/写访问权限。 ...

    sap笔试题(c ).doc

    本文基于提供的文档信息,深入探讨了 C++ 中的关键概念和技术,包括但不限于数组操作、异常处理、类继承与多态性等。这些知识点对于深入理解 C++ 语言特性及其在实际编程中的应用具有重要意义。

    childprocess:C ++ 17类管理Unix子进程

    异常安全 可在符合的应用程序中代替system(3)和popen(3) 先决条件: C ++ 17 类Unix系统 如何构建和运行测试程序 这个软件库包含的子过程库( , )与如Boost.Test单元测试程序一起。 要构建和运行单元测试: ...

    PHP扩展编写点滴 技巧收集

    13. **zval内存管理**:理解zval_dtor(), zval_ptr_dtor()和zval_copy_dtor()的区别很重要。zval_dtor()直接释放zval及其引用的内存,zval_ptr_dtor()则根据引用计数决定是否释放,而zval_copy_dtor()仅进行深拷贝,...

    程序员的自我修养——运行库

    - **全局构造与析构的发生位置**:全局对象的构造和析构发生在特定的段(section)中,通常被称为`.ctor`段和`.dtor`段。在程序启动时,运行库会执行`.ctor`段中的构造函数;而在程序退出时,则执行`.dtor`段中的析...

    如何用C语言编写一个PHP的C扩展.zip

    8. **构建和安装**:运行`phpize`、`./configure --with-my-extension`、`make`和`make install`,完成扩展的编译和安装。 9. **启用扩展**:在`php.ini`中添加`extension=my_extension.so`(或`.dll`,取决于操作...

    单片机浮点运算子程序库.doc

    10. **余弦(FCOS)**、**正弦(FSIN)**、**反正切(FATN)**、**弧度与度数转换(RTOD, DTOR)**:这些函数实现了基本的三角函数和角度单位转换,是图形处理和信号分析的基础。 单片机浮点运算子程序库的设计考虑...

    MCS-51单片机实用子程序库

    - **RTOD** 和 **DTOR**:浮点弧度数与度数之间的转换。 这些子程序库为51单片机的开发者提供了丰富的数学运算工具,简化了复杂的数值处理任务,提高了代码的可读性和复用性,对于涉及数值计算和处理的应用程序...

Global site tag (gtag.js) - Google Analytics