1ms Faster
Home
  • Program

    • Lean in C++
  • Perfromance Engineering

    • [>>>>>]
  • Reading Note

    • [>>>>>]
  • ComputeArch

    • [_]
  • Compiler

    • [_]
  • System

    • [_]
Authoring
  • Categories
  • Tags
GitHub (opens new window)

Quincy Jet

We are.
Home
  • Program

    • Lean in C++
  • Perfromance Engineering

    • [>>>>>]
  • Reading Note

    • [>>>>>]
  • ComputeArch

    • [_]
  • Compiler

    • [_]
  • System

    • [_]
Authoring
  • Categories
  • Tags
GitHub (opens new window)
  • Lean in c++

  • Performance Engineering

  • Misc

  • Reading Notes

    • Effective C++

    • More Effective C++

      • 基础议题
      • 操作符(operators)
      • 异常(exceptions)
        • 异常(exceptions)
          • Item 9:利用 destructors避免泄漏资源
          • Item 10:在 constructors内阻止资源泄漏(resource leak)
          • Item 11:禁止异常(exceptions)流出 destructors之外
          • Item 12:了解“抛出一个 exception”与“传递一个参数”或“调用一个虚函数”之间的差异
          • Item 13:以 Catch-by-reference 方式捕捉 exceptions
          • Item 14:明智运用 exception specifications
          • Item 15:了解异常处理(exception handling)的成本
      • 效率(efficiency)
      • 技术(techniques, idioms, patterns)
      • 杂项讨论,Misc
    • 《C++ 性能优化指南》
  • Wiki
  • Reading Notes
  • More Effective C++
Quincy Jet
2022-06-27
Content

异常(exceptions)

#

# 异常(exceptions)

# Item 9:利用 destructors避免泄漏资源

利用destructor来避免资源的泄露(什么是资源泄露?没有delete的指针), 最好还是使用智能指针的类来处理会比较好;

  • 要么catch到exception之后, 要及时释放资源, 避免资源泄露;

  • 要么就在destructor里面, 增加资源的释放, 即使遇到异常, 退出的时候也会调用析构函数里面的delete;

  • 虚基类(多态基类)一定要有自己的虚dtor函数【Effectie C++里面也用到了】

    使用智能指针, auto_ptr(), shared_ptr(), weak_ptr() 注意他们相关的实现

# Item 10:在 constructors内阻止资源泄漏(resource leak)

利用constructor来避免资源泄露(最好还是使用智能指针的类比较好)

  • 在构造新对象的过程中, 如果构造失败, 就可能会造成资源泄露

  • 析构函数指挥析构已经构造完成的对象, 所以要考虑到在构造对象的时候,是否会发生异常。

  • 所以要直接在构造函数里面对构造失败的异常进行捕获, 并且处理好这些异常, 对野指针进行delete。

  • 把这些指针的删除, 全部包在一个clean up()的函数里面;

  • 指向const的指针, 只能在初始化列表里面进行初始化, 这些对象的初始化过程中的异常, 可以放在一个private函数里面去进行,

  • 不过最好还是使用auto_ptr之类的东西, 直接去管理类的成员数据, 比较方便一些

  • 由于 C++不自动清理那些“构造期间抛出 exceptions”的对象,所以你必须设计你的 constructors,使它们在那种情况下亦能自我清理。

# Item 11:禁止异常(exceptions)流出 destructors之外

别让异常跑出destructor(dtor里面, 就不要再把异常往外抛了)

  1. 可以避免 terminate函数在exception传播过程的栈展开(stack-unwinding)机制中被调用;
  2. 它可以协助确保 destructors 完成其应该完成的所有事情, 程序不会中断。
  3. 也可以dtor里面也可以什么都不做, 就是为了程序能够顺利运行下去, 但是要确保这个异常不会真正影响程序本身

# Item 12:了解“抛出一个 exception”与“传递一个参数”或“调用一个虚函数”之间的差异

弄清楚, 抛出一个异常, 和 传递一个参数之间的区别

一个对象被抛出作为 exception时,总是会发生复制(copy), 但是若是以by value的方式捕获, throw和catch的时候, 都会发生一次临时变量的复制;

void passAndThrowWidget(){
	static Widget localWidget;
	
	cin >> localWidget;
	throw localWidget; // 还是会对localWidget发生copy行为,然后再抛出
}
1
2
3
4
5
6

两种不同的throw语句:

catch(Widget &w){
    ... 
    throw; // 重新抛出这个exception,使它能继续传播
}

catch(Widget &w){
    ...
    throw w; // 处理好之后, 继续往外传播这里catch到的exception
}
1
2
3
4
5
6
7
8
9

三种catch语句:

catch (Widget w) ...
catch (Wiget& w) ...
catch (const Widget& w) ...
1
2
3

execption和catch子句之间 不能发生隐式的类型转换:

void func(int value){
    try{
        if(someFunction()){
            throw value;
        }
    } 
    catch(double d){ // 上面throw的是一个int类型, 这里是catch不到这个value的
        ...
    }
}
1
2
3
4
5
6
7
8
9
10

但是,类型转换是能够发生在C++ exceptions的继承体系中的,可以理解为exception支持多态:

img

从有形指针抓换为无形指针的转换,catch是支持的:

catch(const void*){
    ...
}
1
2
3

# Item 13:以 Catch-by-reference 方式捕捉 exceptions

  • by value的局部变量复制问题, 并且,如果我们要继承exception定义自己的exception子类, 使用by value,虽然支持catch, 会发生slicing的问题, 也就是多态只能够针对地址类型才能够有效

  • by pointer 会有局部对象问题需要考虑,用起来考虑的问题比较多(catch之后要不要删除?是否返回了局部对象的地址?)

  • 所以要以Catch-by-reference的方式捕获一个exception;

# Item 14:明智运用 exception specifications

明智地运用exception specification, 因为一旦使用, 就和async的使用一样, exception也会有内外传递的问题;

void func() throw(int); // 这里指定func()会抛出一个int类型的exception
// 继承exception定义自己的exception的时候,也是这种形势, 需要重新定义what的行为;
1
2

# Item 15:了解异常处理(exception handling)的成本

  • 要清楚异常处理带来的成本;这些东西是C++本身就包括在里面的

  • 粗略估计,如果使用 try 语句块,代码大约整体膨胀 5%~10%,执行速度亦大约下降这个数。这是在假设没有任何 exceptions 被抛出的情况下。此处我们所讨论的只是“代码中出现 try 语句块”的成本而已。

  • 主要是时间和空间上面的成本;

  • 需要讨论, C++ runtime时候, 编译, 连接的时候,对这些exceptions是怎么处理的?要使用profile工具针对特定程序做特定的性能分析;

操作符(operators)
效率(efficiency)

← 操作符(operators) 效率(efficiency)→

Copyright © 2017-2023 Quincy Jet | MIT License
  • Auto
  • Light
  • Dark
  • Read