命名空間的定義與使用(轉)
1. 命名空間的定義:由關鍵字 namespace後邊接著命名空間名字,之後接一對花括弧括住的一塊聲明和定義;
//17.2.A.h 頭文件定義命名空間 primer_17_2
//17.2.A.h 頭文件定義命名空間 primer_17_2 namespace primer_17_2 { //定義成員類A class A { public: int getA(); //成員函數,定義在命名空間的定義文件中,並且在命名空間內部定義; int getB(); //成員函數,定義在命名空間的定義文件中,但是,它是在命名空間外部定義的,請查看下邊的 17.2.A.cpp 定義文件; int fun() { return 0; } //成員函數及其實現體,在類內部定義,也就是在命名空間的頭文件中定義; friend A operator+(const A &lhs, const A &rhs); //將操作符函數聲明為友元函數,因為該函數被定義成了非成員函數; private: int v; }; A operator+(const A &lhs, const A &rhs); //為命名空間primer_17_2聲明一個加操作符成員,必須在命名空間頭文件以外定義,在命名空間實現文件中定義時:既可以在命名空間內部定義也可以在外部定義,外部定義時必須指定命名空間限定符;在其他文件中定義時:必須指定命名空間限定符,以指明函數屬於哪個命名空間; char get(); //為命名空間primer_17_2聲明一個普通成員,方法同加操作符,本例中,該函數定義在了其他文件中,請看文件:17.2.C.cpp; const char ch1 = ‘a‘; //ok 為命名空間primer_17_2定義一個字符常量並初始化,常量必須設置初始值; static char ch2 = ‘b‘; //ok 為命名空間primer_17_2定義一個靜態字符常量,並設置初始值,在使用的程序中可以修改; static char ch3;// = ‘c‘; //ok 為命名空間primer_17_2定義一個字符常量,不設置初始值,在使用的程序中可以修改; //static const char ch4; //error, 常量必須設置初始值; static const char ch4 = ‘d‘; //ok 靜態的常量,設置了初始值; extern char ch5; //聲明字符變量ch5,在使用的程序中進行定義,如:char primer_17_2::ch5,或 char primer_17_2::ch5 = ‘e‘,必須在extern聲明後,再在命名空間實現文件中定義該變量; extern int n; //聲明定義方法同上; } //; 這裏不需要以分號結尾
在花括弧中可以出現 能夠全局作用域中出現的任意聲明:類,變量(以及他們的初始化),函數(以及他們的定義),模板以及其他的命名空間
2. 命名空間成員的定義:
(a) 命名空間中,類的成員函數可以在命名空間的類的內部定義,也可以在命名空間的實現文件中定義;如:上述的類成員函數int getA()在命名空間的實現文件中定義,而成員函數 int fun();則在類內部定義,自動成為內聯函數;
(b) 命名空間的直接成員,必須在頭文件聲明,在實現文件中定義,如:上述 char get()與 加操作符函數 定義在命名空間的實現文件中;
//17.2.A.cpp #include "17.2.A.h" namespace primer_17_2 { int A::getA() //類A的成員函數,在命名空間實現文件中定義,並且在命名空間內部定義; { return v; } A operator+(const A &lhs, const A &rhs) //命名空間的直接成員函數,在命名空間實現文件中定義,並且在命名空間內部定義; { A a; a.v = lhs.v + rhs.v; return a; } /*char get() //註釋掉了,為了說明在其他文件中如何定義命名空間的直接成員,查看 17.2.C.cpp { return ‘m‘; } */ int n = 0; //註意變量n的定義,首先在頭文件中extern聲明,然後在命名空間實現文件中進行定義,賦值或不賦值都可以; char ch5 = ‘e‘; //聲明與定義方法同上; } int primer_17_2::A::getB() //類A的成員函數,在命名空間實現文件中定義,並且在命名空間外部定義; { return 100; } char primer_17_2::get(char c) //命名空間的直接成員函數,在命名空間實現文件中定義,並且在命名空間外部定義; { return c; } // 17.2.C.cpp,觀察primer_17_2 的直接成員 char get();的定義: #include "17.2.C.h" #include "17.2.A.h" namespace AA { int getAA() { return -1; } //error, primer_17_2的 成員get在這裏定義是非法的,這裏的作用域屬於命名空間AA; /* char primer_17_2::get() { return ‘z‘; } */ } //ok,在這裏定義必須指定primer_17_2限定符; char primer_17_2::get() { return ‘z‘; }
3. 命名空間成員定義總結:
(a)命名空間直接成員函數:在命名空間頭文件以外定義時,既可以在命名空間實現文件中定義,也可以在其他文件中定義:
(a.1) 在命名空間實現文件定義時:既可以在命名空間內部(花括弧以內)定義也可以在外部(花括弧以外)定義,外部定義時必須指定命名空間限定符;
(a.2) 在其他文件中定義時:必須指定命名空間限定符,以指明函數屬於哪個命名空間;
(b)類類型及模板類型:其成員函數可以在類內部定義,也可以在命名空間的實現文件定義,這時可以在內部也可以在外部,在其他文件中定義時須指定命名空間限定符;
(c)非const以及非static直接變量,必須以extern進行聲明,然後在使用該變量的地方進行定義,如上述例子中的變量ch5與n的聲明與定義;
(d)命名空間可以不連續定義,即在多個文件中進行成員的聲明和定義,這些成員的聲明和定義是累積的,共同組成同一個命名空間;
4. 命名空間的使用:
#include <iostream> #include "17.2.A.h" using namespace std; using namespace primer_17_2; int main() { A a; A b; A ab = a + b; cout << "ab.v:" << ab.getA() << endl; cout << "primer_17_2::get():" << get() << endl; cout << "primer_17_2::ch1:" << ch1 << endl; ch2 = ‘b‘; //primer_17_2::ch2 cout << "primer_17_2::ch2:" << ch2 << endl; ch3 = ‘c‘; cout << "primer_17_2::ch3:" << ch3 << endl; cout << "primer_17_2::ch4:" << ch4 << endl; cout << "primer_17_2::ch5:" << ch5 << endl; cout << "primer_17_2::n:" << n << endl; return 0; }
運行結果:
ab.v:100
primer_17_2::get():z
primer_17_2::ch1:a
primer_17_2::ch2:b
primer_17_2::ch3:c
primer_17_2::ch4:d
primer_17_2::ch5:e
primer_17_2::n:0
https://blog.csdn.net/ljq32/article/details/7937742#
命名空間的定義與使用(轉)