Using声明和指令的工作原理

对于C++编译器,那么名字可见是至关重要的,太过的名字可见将导致名字查找效率的降低,而名字太少将导致无法找到所需类型或函数的名字,从而导致编译错误。除了最常用的include可以导入可见名字之外,using关键字也可以导入名字到特定的编译单元中(单个cpp文件)。
区别:
Using声明: using namespace std;
Using指令:  using N::Widget;

Using用于导入特定名字空间下的名字实体,可以是全部名字实体(using namespace std;),也可以是特定的名字实体(using std::map;)。

工作原理:using声明将获取的是在遇到using声明(指令)瞬间所见到的名字空间中的实体。这点是可以理解的,这样的工作方式有利于避免名字冲突(过多导入污染),并加入名字查找过程。但这同时意味着:只有在using namespace std;语句之前所include的std头文件的名字实体被引入,即using并未引入所有来自std的名字实体。
Using关键字定理:绝对不要在include之前使用using声明或指令。
推论:不要在头文件中使用using声明或指令,相反应该使用名字空间限定所有的名字,尤其是来自其他名字空间的名字。(原因:头文件并不知道完全的include信息,头文件总是被用于其他cpp中,其后总会出现另外的include)
例子:
// snippet 1
namespace A {
 int f(double);
}

// snippet 2
namespace B {
  using A::f;
  void g();
}

// snippet 3
namespace A {
 int f(int);
}

// snippet 4
void B::g() {
  f(1);                         // which overload is called?
}
这几个文件先后出现顺序将决定f(1)是否可编译(所有的f函数定义均不可见)?以及重载哪个函数(哪些函数可见,并参与重载)。
错误地使用using将导致名字空间污染,或错误地导入不完整的名字空间的瞬间快照(导致无法找到特定名字实体)。在头文件中,使用using将使这个问题更加严重(多处使用,使用顺序不可控)。
例外:编写类成员级的using声明以导入所需的基类成员名字是一个合法技巧,只要这样才能避免基类的名字被屏蔽,如重载函数不可见问题。(见派生类的函数重载)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值