[C++再学习系列] Using声明和指令的工作原理
2012-11-13 19:01
387 查看
对于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 声明以导入所需的基类成员名字是一个合法技巧,只要这样才能避免基类的名字被屏蔽,如重载函数不可见问题。(见派生类的函数重载)
相关文章推荐
- [C++再学习系列] Using声明和指令的工作原理
- [C++再学习系列] Using声明和指令的工作原理
- C++ 学习笔记(18)异常处理(noexcept说明符和noexcept运算符、构造函数的try和catch)、命名空间(using声明和using指示)、多继承(虚继承)
- [C++再学习系列] 变量的声明、定义与extern关键字
- 关于using声明与using指令 c++
- [C++再学习系列] 函数声明与STL容器构造
- Using声明和指令的工作原理
- [C++再学习系列] 函数声明与STL容器构造
- C++_命名空间namespace 与 using编译指令 与 using声明使用。
- Using声明和指令的工作原理
- [C++再学习系列] 变量与声明时初始化
- Using声明和指令的工作原理
- C++ 学习系列(三) #if #elif #else 和 #endif指令
- [C++再学习系列] 函数模板和类模板
- c++ Premier 学习笔记(unit2 变量和基本类型 -声明与定义
- [C++再学习系列] 二元操作符重载
- 立此存照(18)[C++]using声明与using指示的区别
- 【C++学习之路】VS2015中cout、cin未声明的标识符错误的处理
- C++ 学习笔记(3)命名空间using、字符串、string、vector、迭代器、数组
- [C++再学习系列] 虚函数的4条规则