C/C++黑魔法-随处安放的try

一般try..catch块语句都用在函数体内,但是也有例外的时候,对于作者这种懒人,写语句能省则省。看看我是怎么操作的吧。

1.”随处安放”在函数体’外’

  • 看到以下代码相信不少人会认为语法错误吧,写少了一对{},实则下面这段函数是没问题的。

    1
    2
    3
    4
    5
    6
    7
    void func()
    try {
    printf("This is a function.");
    }
    catch (...) {

    }
  • 相当于

    1
    2
    3
    4
    5
    6
    7
    8
    9
    void func() 
    {
    try {
    printf("This is a function.");
    }
    catch (...) {

    }
    }

2.为什么会这样,是什么黑魔法导致这样?

  先看看try块的语法:

  • 函数try块是一种函数体的替代语法形式,也是函数定义的一部分。

  一般以下形式表示:

  • catch称为处理块序列(可以是多个)
  • 函数体中的任何语句中抛出的所有异常,将控制转移到处理块序列(catch)中。
    1
    2
    3
    4
    5
    6
    try {
    ...
    }
    catch (...) {
    ...
    }

  解开魔法

  • 根据try块语法,try函数块可以作为函数体的替代。

3.这个有什么用?

  当然有用啦。存在即合理,这魔法当然需要做点什么啦?!

  1. 构造函数成员初始化器列表中捕获异常,主要是构造过程中抛出异常清理构造过程中已经申请的内存,如果不能清空已构造的内存则会导致内存泄漏。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    class A
    {
    public:
    A(int count) try : m_count(count) {
    new B();
    ...
    throw;
    }
    catch (...) {
    // 清空构造函数所产生的内存, 如清空new B()申请的内存。
    }

    ~A() try {
    }
    catch (...) {
    }

    private:
    int m_count;
    };
  2. 用在debug调试中,只要定义DEBUG宏即能使用try...catch机制。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void func()
    #ifdef DEBUG
    try
    #endif
    {
    ... // 一些操作
    }
    #ifdef DEBUG
    catch(...) {
    }
    #endif /* DEBUG */

  • 文章首发于微信公众号:Qt君