1. 程式人生 > >命名空間的定義與使用(轉)

命名空間的定義與使用(轉)

關鍵字 函數定義 details tails r+ 自動 () rhs ostream

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#

命名空間的定義與使用(轉)