很少有人知道的c++中的try块函数
c++有一些在现实世界中很少看到的结构。这些结构有着自己的用法,但是要特别小心保守的予以运用。就像是网站 The Old New Thing首页标题上面的说的那样:
“代码通常被读的次数原因超过了被写的次数,所以计划要遵循此道。”
在下面将介绍一些很少有人能够知道的c++构造函数,包括其中的运用场景,语法和陷阱。
运用场景
try函数块的应用场景一般局限于下面几个:
(1)构造函数初始化列表;
(2)基类构造含数据;
(3)析构函数;
语法
对于函数
1 |
void
f() try
{ /*...*/
} catch
(...) { /*...*/
} |
这等价于
1 |
void
f() { try
{ /*...*/
} catch
(...) { /*...*/
} } |
对于构造函数初始化列表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 |
struct
A : public
B { A() try
: B(), foo(1), bar(2) { // constructor body } catch
(...) { // exceptions from the initializer list are caught here // but also rethrown after this block (unless the program is aborted) } private : Foo foo; Bar bar; }; |
对于析构函数来说,跟正常函数的使用方法是类似的
1
2
3
4
5
6
7
8
9
10
11
12
13 |
struct
A { ~A() try { // destructor body } catch
(...) { // exceptions from the destructor are caught here // but also rethrown after this block (unless the program is aborted) } }; |
陷阱
- 任何在构造函数和析构函数中捕捉的异常,默认情况下都会被重新抛出。这样的话,大多是情况下当捕捉到一个异常的时候,你能够做的事情就是用日志记录,或者是做一些清理工作。不管一个对象因为什么原因而失败了,你都不应该尝试去保存它的实例。
- 在函数catch块中的return语句表现的跟函数中的返回语句一样;
- 但控制流走到catch模块最后的时候,函数将返回。如果没有任何返回语句而且函数返回类型是非void的,那么行为将会是不确定的。
- try块函数主要有一些非直观的行为:
- 从命名空间范围内定义的构造函数中抛出的异常无法捕捉。
- 从static变量中获取的析构函数的对象中抛出的异常无法捕捉。
如上,try模块函数在进行代码审查的时候至少是应该引起重视的。try块函数使用并非都是错的,在一些上没有提到的用户场景中用到的时候,很容易出现问题。
来源http://szelei.me/rarely-known-cpp-constructs-part-1-function-try-blocks/
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。