首页 > 代码库 > namespace 命名空间

namespace 命名空间

一、命名空间的定义

namespace 命名空间的名字 {类/变量/函数/模板/其他命名空间};

命名空间空间可以定义在全局作用域和其他命名空间中,但不能定义在函数或类的内部。

 

二、命名空间的作用域

每一个命名空间都是一个作用域,定义在某个命名空间中的名字可以被该命名空间内的其他成员访问,也可以被这些成员的内嵌作用域中的任何单位访问。

namespace nsp{
    int num=10;
    class ab
    {
        public:
        int val(){return num;}
    };
    }
int val(){return num;}     //num未定义

 

命名空间可以使不连续的,也就是说可以定义一个新的命名空间,也可以为已经存在的命名空间添加新成员

namespace nsp{
    int num=10;
    class ab
    {
    public:
        int val(){return num;}
        ab& operator=(const ab&);
    private:
        string Simat;
    };
    }
namespace nsp{
    ab& ab::operator=(const ab&rs)
    {
        if(this!=&rs)
        {
            ab ls(rs);
            string temp=ls.Simat;
            ls.Simat=Simat;
            Simat=temp;
        }
        return *this;
    }
}

 

全局作用域中定义的名字也就是定义在全局命名空间中,他以隐式的方式声明,因而也不会有名字。

我们访问可以用

::member_name   //表示一个全局命名空间的一个成员

 

未命名的命名空间指那么namespace之后直接接花括号,他具有静态生命周期(用于取代静态声明)。

形如 namespace {int i;}

 

三、命名空间的使用

命名空间别名

namespace 别名=原来的名字; //主要用于名字过长

using 声明

一条using声明语句一次只引入命名空间的一个成员

using 指示

using指示将某个命名空间所有名字可见

namespace pro1
{
    int i=1;
    int j=2;
}
namespace pro2
{
    int k=3;
    int m=4;
}
void f()
{
    using pro1::i;     //using声明
    using namespace pro2;   //using 指示
    cout<<i<<" "<<k<<endl;
    //  cout<<j<<endl;     error: ‘j‘ was not declared in this scope
}

 

四、命名空间查找规则

常规查找规则:由内到外依次查找每个外层作用域。

实参相关的查找:当我们给函数传递一个类类型对象时,除了常规的作用域查找,还继续查找实参类所属的命名空间(指针与引用同样有效)

//下面两种调用等价
operator>>(std::cin,s);  //在没有声明string的operator>>时我们可以直接使用

std::string s;
std::cin>>s;

友元声明与实参相关的查找:

namespace pro1
{
    class C{
        friend void f2();
        friend void f(const C&);
    };
    void f2()
    {

    }

    void f(const pro1::C& a)
    {

    }
}



void f3()
{
    pro1::C cobj;
    f(cobj);    //f在C所属的命名空间进行了隐式声明(实参cobj),所以可以被找到
//   f2();      //没有形参所以找不到
}

重载与命名空间

using声明的是一个名字所以对于一个函数的声明只能有函数名

using NS::print(int);  //这是错误的

using NS::print;  //只声明一个函数名

因而一个using声明会包括所有的重载函数版本

using指示则会将命名空间的某个函数与作用域内的同名函数都作为重载函数版本

namespace AW
{
   int print(int);  
}

namespace Pri
{
  double print(double);  
}

using namespace Pri;
using namespace AW;

string print(string);

int main()
{
  print(1);   //调用AW::print
  print(1.1);  //调用Pri::print
  print("abc");    
  return 0;    
}

 

namespace 命名空间