1. 程式人生 > >namespace 命名空間

namespace 命名空間

err 不能 blog cnblogs 括號 div ima 會有 name

一、命名空間的定義

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 命名空間