C++:异常、名字空间、预处理指令

异常

当一个异常被抛出后,C++的运行时支持系统“在调用栈中向上”搜索与抛出对象类型匹配的catch子句,即查找抛出异常的函数中的try语句,然后在抛出异常的函数的调用者中查找,再在更上层的调用者中查找,依次类推,直到找到匹配的catch语句。
如果找不到匹配的catch子句,程序就会终止。在搜索过程中遇到的每个函数中,以及每个作用域中,都会调用析构函数进行清理工作,这个过程被称为堆栈解退(stack unwinding)。

一旦对象的构造函数执行完毕,我们就认为对象已经构造出来了,而在堆栈解退过程中,或者退出对象作用域时,对象被销毁。
这意味着,作用域中还没有完全构造完成的对象(某些成员或基类已经构造完成,而另外一些没有构造完成)、数值和变量能够被正确处理。子对象当且仅当构造完毕后才能被销毁。

  • 不要在析构函数中抛出异常!这条原则意味着析构函数不能失败。
//永远不要这样做!
X :: ~X() {if(in_a_real_mess())  throw Mess();}

定义这样的原则的主要原因是,如果析构函数在堆栈解退过程中抛出一个异常(而它自身又没有捕获这个异常的话),我们并不知道应该处理哪了个异常。

名字空间

名字空间(namespace)将相关的声明组织在一起,用来避免名字冲突:

int a;

namespace Foo{
    int a;
    void f(int i)
    {
        a +=i;    //这是Foo的a(Foo::a)
    }
}

boid f(int);

int main()
{
    a = 7;          //这是全局a(::a)
    f(2);           //这是全局f(::f)
    Foo::f(3);      //这是Foo的f
    ::f             //这是全局f(::f)

我们可以显式地用名字空间名来限定名字(如Foo::f(3)),或者用::来限定名字(::f(2)),后者表示全局作用域。
我们可以使用一条单一的名字空间指令,使名字空间中的所有名字都可以被使用。eg:

using namespace std

在使用using指令时一定要小心,虽然获得了名字使用上的便利性,但可能就会导致潜在的名字冲突。
特别的,不要在头文件中使用using指令
我们可以使用名字空间声明,使名字空间中的某个名字可以访问:

using Foo::g;
g(2);               //这里是Foo的g(Foo:g)

预处理指令

每个C++实现都包含预处理器(preprocessor)。理论上,预处理器在编译器之前运行,恰当地将我们编写的源码转换为编译器所需要的形式。
在实际中,预处理过程通常集成在编译器中,而且除非它引起了错误,否则对我们来说没有意义。
以#开头的代码行都是预处理指令。

  • #include
#include "file.h"

这条指令告诉预处理器,在源码中指令出现的这个位置包含file.h的内容。
对于标准头文件,我们使用<…>而不是”…”,例如:

#include<vector>

这是包含标准头文件的建议语法。

  • #define
    预处理器实现一种字符处理机制,这种机制被称为宏代换(marco substitution)。例如,我们可以为字符串定义名字:
#define FOO bar;

因此,凡是出现FOO的地方,都会被替换成bar:

int FOO = 7;
int FOOL = 9;

进过预处理器处理,编译器看到的将是:

int bar = 7;
int FOOL = 9;

定义带有参数的宏:

#define MAX(x,y)(((x)>(y))?(x) : (y))

我们可以这样使用这个宏:

int xx = MAX(FOO+1, 7);
int yy = MAX(++xx, 9);

这段代码会被扩展为:

int xx = (((bar+1)>(7))?(bar+1) : (7));
int yy = (((++xx)>(9))?(++x) : (9));        //xx“悄悄”做了两次递增运算

如果一定要使用宏,一般全部使用大写字母来定义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值