chapter18_命名空间

命令空间

  1. 每个命名空间都是一个作用域
    位于该命名空间之外的代码必须明确指出所用的名字属于哪个命名空间
  2. 命名空间可以是不连续的
  3. 定义命名空间成员的方法:
重新打开命名空间:
#include "....h"
namespace cplusplus_primer {
//定义命名空间中的成员
}
在命名空间之外定义:
cplusplus_primer::xxx cplusplus_primer::operator+(const xxx& lhs,const xxx& rhs)
{
}
  1. 全局命名空间 ::member_name
  2. 嵌套的命名空间
namespace A{
    namespace B {
    //B中的成员
    int data;
    }
    namespace C {
    //C中的成员
    }
}
A::B::data
  1. 内联命名空间
  2. 未命名的命名空间(定义在未命名空间中的实体具有独立于其它文件的效果,相当于static)
    每个文件定义自己的未命名空间,未命名的命名空间仅在文件内部有效,无法跨文件。
    定义在未命名的命名空间的名字可以直接使用,因为没有命名空间的名字来限定。于是此类命名空间定义在文件的最外层作用域中有个注意的地方:
int i;
namespace {
    int i;
}
int main()
{
    i = 10;//出现二义性,不知道是全局作用域中的i,还是未命名的命名空间中的i
}
解决方法:
namespace local { //利用嵌套
    namespace {
        int i;
    }
}
  1. 命名空间的别名

namespace primer = cplusplus_primer;

  1. using 声明
    有效范围从using 声明的地方开始到using 声明的作用域结束为止。
    可以出现在全局作用域,局部作用域,命名空间作用域中和类作用域中。
    在类的作用域中国,声明语句只能指向基类成员。
  2. using 指示(少用)
    可以出现在全局作用域,局部作用域,命名空间作用域中,但不能出现在类的作用域中。

例子:using namesapce std;

using 指示的作用是令整个命名空间的所有内容变得有效。using 指示一般被看做是出现在最近的外层作用域中。

namespace A {
    int i, j;
}
void f()
{
    using namespace A; //把A中的名字注入到全局作用域中
    cout << i * j << endl; 
}
  1. 命名空间内部名字的查找按由内向外依次查找每个外层作用域,直到最外层的全局命名空间查找过程为止。
    有个特例:当我们给函数传递一个class类型的对象时,除了在常规的作用域查找外还会查找实参类所属的命名空间。 例如:
std::string s;
std::cin >> s; == operator>>(std::cin, s);
因为s是class string的对象,所以会查找string所属的命名空间: std。找到了string的operatot>>函数
  1. 函数重载与命名空间
  • 与实参相关的查找带来的重载
namespace NS {
    class A {};
    void display(const A&) {}
}
class B : public NS:A {};
void display(const B&) {}
int main()
{
    B b1;
    display(b1); //产生了重载
}
  • 重载与using 声明

using NS::print; //引入了NS中print的所有版本。
//如果由于导入了NS中的某个版本的print函数与当前作用域的print函数冲突,则报错

  • 重载与using 指示

using namespace NS;
如果由于导入了NS中的某个版本的print函数与当前作用域的print函数冲突,与using 声明相反的是,不报错,除非代码中使用了这个冲突版本的print函数。

你可能感兴趣的:(chapter18_命名空间)