chap 16 名稱空間

42
1 1 /42 /42 Chap 16 Chap 16 名名名名 名名名名 子子 子子子 子子子子子子子子子 子子子子子 子 ,,。 子子 子子子 子子子子子子子子子 子子子子子 子 ,,。 子子子子子子子子子 《》 子子子子子子子子子 《》 子子子子 子子子子 (namespace) (namespace) 子子子子子子子子子子子子子子子子子 子子子子子子子子子子子子子子子子子 子子子子子子子子子子子子子子子子子子子子

Upload: penelope-herman

Post on 03-Jan-2016

89 views

Category:

Documents


1 download

DESCRIPTION

Chap 16 名稱空間. 子曰:「名不正,則言不順 ﹔ 言不順,則事不成。」 《 論語 ﹒ 子路第十三 》 名稱空間 (namespace) 的目的在於避免大型程式庫之間因為使用相同名稱而造成衝突。. Chap 16 名稱空間. 16.1  因為名稱相同而造成的問題 16.2  名稱空間的基本語法 16.3  名稱空間成員的存取 16.4  使用「 using 指令」和「 using 宣 告」以存取名稱空間的成員 16.5  標準名稱空間 16.6  未命名的名稱空間. 因為名稱相同而造成的問題. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Chap 16    名稱空間

11/42/42

Chap 16 Chap 16 名稱空間名稱空間

子曰:「名不正,則言不順﹔言不順,則事不成。」子曰:「名不正,則言不順﹔言不順,則事不成。」《論語﹒子路第十三》《論語﹒子路第十三》

名稱空間 名稱空間 (namespace)(namespace) 的目的在於避免大型的目的在於避免大型程式庫之間因為使用相同名稱而造成衝突。 程式庫之間因為使用相同名稱而造成衝突。

Page 2: Chap 16    名稱空間

22/42/42

Chap 16 Chap 16 名稱空間名稱空間

16.116.1  因為名稱相同而造成的問題 因為名稱相同而造成的問題 16.216.2  名稱空間的基本語法 名稱空間的基本語法 16.316.3  名稱空間成員的存取 名稱空間成員的存取 16.416.4  使用「 使用「 usingusing 指令」和「指令」和「 usingusing 宣宣

告」以存取名稱空間的成 告」以存取名稱空間的成員員

16.516.5  標準名稱空間 標準名稱空間 16.616.6  未命名的名稱空間 未命名的名稱空間

Page 3: Chap 16    名稱空間

33/42/42

因為名稱相同而造成的問題因為名稱相同而造成的問題

開發大型程式時,因為名稱相同而造成開發大型程式時,因為名稱相同而造成問題的機會就會大增。問題的機會就會大增。

限制了我們使用同名常數和同名類別的限制了我們使用同名常數和同名類別的機會,否則在編譯時就會發生機會,否則在編譯時就會發生重複宣告重複宣告 (multiple declaration) (multiple declaration) 的錯誤,無法的錯誤,無法正確使用程式庫 正確使用程式庫 (library)(library) 。。

Page 4: Chap 16    名稱空間

44/42/42

因為名稱衝突而造成因為名稱衝突而造成無法引用既有程式的問題無法引用既有程式的問題 由於常數由於常數 GainGain 和和 structstruct 資料型態資料型態 MemberMember 的名稱相同,一次的名稱相同,一次

只能選擇一個標頭檔使用只能選擇一個標頭檔使用

#ifndef FIRST_H #define FIRST_H const double

Gain = 5.9; struct Member { char Name[20]; int Phone; }; #endif

#ifndef SECOND_H #define SECOND_H const double

Gain = 2.6; struct Member { int IdNum;

char Name[20]; int Profit; }; #endif

// Test.cpp #include <iostream> using std::cin; using std::cout; using std::endl; #include "First.h" int main() { Member Ma= { "George Wang", 23246352

};

...; return 0; }

First.h

Second.h

Test.cpp

Page 5: Chap 16    名稱空間

55/42/42

名稱空間的基本語法 名稱空間的基本語法

名稱空間 名稱空間 (name space) (name space) 的宣告敘述之後沒有「;」做為結尾。的宣告敘述之後沒有「;」做為結尾。例如:例如:

namespace MyNamespace namespace MyNamespace // // 程式庫的介面程式庫的介面{{ const double Gain = 5.9; const double Gain = 5.9; // // 常數的定義 常數的定義 struct Member struct Member // struct// struct 資料型態的宣告資料型態的宣告 { { char Name[20]; char Name[20]; int Phone; int Phone; };}; double Fnc(double); double Fnc(double); // // 函數的宣告函數的宣告 (( 函數的原函數的原

型型 ))}}

Page 6: Chap 16    名稱空間

66/42/42

名稱空間的宣告可以用累積的方式完成名稱空間的宣告可以用累積的方式完成

namespace MyNamespacenamespace MyNamespace{{ const double Gain = 5.9;const double Gain = 5.9;}}namespace MyNamespacenamespace MyNamespace{{ struct Memberstruct Member { { char Name[20]; char Name[20]; int Phone; int Phone; };}; double Fnc(double);double Fnc(double);}}

Page 7: Chap 16    名稱空間

77/42/42

名稱空間成員的存取 名稱空間成員的存取

名稱空間的名稱空間的成員成員 (member): (member): 名稱空間所含名稱空間所含的各個項目。的各個項目。

「「 :::: 」」 : : 範圍確認運算子範圍確認運算子 (scope resolutio(scope resolution operator) n operator) 。。

要存取名稱空間的成員時要存取名稱空間的成員時 ::名稱空間的名稱 名稱空間的名稱 + + 範圍確認運算子 範圍確認運算子 + + 該成該成員的名稱。 員的名稱。 – 例如:例如:

MyNamespace::MyNamespace::Gain;Gain;MyNamespace::MyNamespace::Fnc();Fnc();

Page 8: Chap 16    名稱空間

88/42/42

資格修飾子資格修飾子 (qualifier)(qualifier)

資格修飾子資格修飾子 : : 名稱空間的名稱加上範圍確認名稱空間的名稱加上範圍確認運算子。運算子。「「 MyNamespace::MyNamespace:: 」就是一個典型的資格」就是一個典型的資格修飾子。修飾子。

使用名稱空間中宣告的使用名稱空間中宣告的 structstruct 資料型態來資料型態來定義定義實例實例 (instance) :(instance) :MyNamespace::MyNamespace::Member Ma = {"George WanMember Ma = {"George Wang", 23246352};g", 23246352};

也就是說,耍在也就是說,耍在 structstruct 資料型態的名稱前資料型態的名稱前加上資格修飾子。加上資格修飾子。

Page 9: Chap 16    名稱空間

99/42/42

巢狀名稱空間 巢狀名稱空間 (nested namespace)(nested namespace)

名稱空間的成員是另一個名稱空間。例如:名稱空間的成員是另一個名稱空間。例如:namespace NS1namespace NS1{{int Size;int Size;namespace NS2namespace NS2{{

const double Ratio;const double Ratio;}}

}} 巢狀名稱空間的內部成員必需套用所有名稱空間的名巢狀名稱空間的內部成員必需套用所有名稱空間的名

稱:稱:int x = int x = NS1NS1::Size;::Size;double y = double y = NS1::NS2::NS1::NS2::Ratio;Ratio;

Page 10: Chap 16    名稱空間

1010/42/42

名稱空間的別名 名稱空間的別名 (alias)(alias)

簡化超長的名稱空間名稱。例如,有個名稱很長的名簡化超長的名稱空間名稱。例如,有個名稱很長的名稱空間:稱空間:namespace Micro_Soft-Company_Namespacenamespace Micro_Soft-Company_Namespace{{ char Employer[2500][20];char Employer[2500][20]; double Fnc(double);double Fnc(double);}}

可以使用名稱空間別名敘述 可以使用名稱空間別名敘述 (namespace alias stat(namespace alias statement ):ement ):namespace namespace MSCMSC = = Micro_Soft-Company_Namespace;Micro_Soft-Company_Namespace;

Page 11: Chap 16    名稱空間

1111/42/42

使用名稱空間別名 使用名稱空間別名 (alias) (alias) 存取成員存取成員

可以使用較簡短的方式存取其成員,例如:可以使用較簡短的方式存取其成員,例如:char Head[20] = char Head[20] = MSC::MSC::Employer[23];Employer[23];

使用名稱空間別名敘述可以一次取代兩層巢使用名稱空間別名敘述可以一次取代兩層巢狀名稱空間的關係:狀名稱空間的關係:namespace NS12 = NS1::NS2;namespace NS12 = NS1::NS2;

此後成員的存取就可以精簡成:此後成員的存取就可以精簡成:double y = NS12::Ratio;double y = NS12::Ratio;

Page 12: Chap 16    名稱空間

1212/42/42

程式庫的分割程式庫的分割 : : 介面與實作介面與實作

介面部份介面部份 (interface part): (interface part): 包括常數宣告和包括常數宣告和函數原型的部份。函數原型的部份。

實作部份實作部份 (implementation part): (implementation part): 含有演含有演算細節之函數定義的部份。算細節之函數定義的部份。

通常進一步將龐大的程式庫區分成數個檔案。通常進一步將龐大的程式庫區分成數個檔案。譬如說,可以將「介面部份」儲存成一個叫譬如說,可以將「介面部份」儲存成一個叫做做 MyLib.hMyLib.h 的檔案,而將「實作部份」儲存的檔案,而將「實作部份」儲存成一個稱為成一個稱為 MyLib.cppMyLib.cpp 的檔案。的檔案。

Page 13: Chap 16    名稱空間

1313/42/42

實作部份的寫法 實作部份的寫法 (1/2)(1/2)

(1)(1)在名稱空間主體之中定義函數在名稱空間主體之中定義函數例如:例如:

// MyLib.cpp// MyLib.cpp#include "MyLib.h"#include "MyLib.h"namespace MyNamespacenamespace MyNamespace{{

double Fnc(double x)double Fnc(double x){ { // // 函數 函數 Fnc() Fnc() 的演算細節 的演算細節 }}

}}

Page 14: Chap 16    名稱空間

1414/42/42

實作部份的寫法 實作部份的寫法 (2/2)(2/2)

(2)(2)在名稱空間主體之外定義函數在名稱空間主體之外定義函數例如:例如:

// MyLib.cpp// MyLib.cpp

#include "MyLib.h"#include "MyLib.h"

double double MyNamespace::MyNamespace::Fnc(double x)Fnc(double x)

{ {

// // 函數函數 Fnc()Fnc() 的演算細節的演算細節}}

Page 15: Chap 16    名稱空間

1515/42/42

實例介紹實例介紹

在檔案在檔案 First.hFirst.h 和和 Second.hSecond.h 內,分別宣告了內,分別宣告了 NS1NS1 和和NS2NS2 兩個名稱空間。兩個名稱空間。 NS1NS1 和和 NS2NS2 兩個名稱空間的同兩個名稱空間的同名函數名函數 Fnc() Fnc() 實作部份寫在檔案 實作部份寫在檔案 FncLib.cppFncLib.cpp 裏面。裏面。

檔案檔案 Test.cppTest.cpp 是主程式,分別使用名稱空間是主程式,分別使用名稱空間 NS1NS1 和和NS2NS2 中的各成員。中的各成員。

以以 Borland C++ Command Line CompilerBorland C++ Command Line Compiler 的使用方的使用方式為例,式為例,本程式在本程式在 DOSDOS 下的編譯指令為:下的編譯指令為:

bcc32 Test FncLibbcc32 Test FncLib

Page 16: Chap 16    名稱空間

1616/42/42

範例程式 檔案 範例程式 檔案 First.h First.h

// First.h// First.h#ifndef FIRST_H#ifndef FIRST_H#define FIRST_H#define FIRST_Hnamespacenamespace NS1 NS1 // // 宣告名稱空間 宣告名稱空間 NS1NS1{{ const double Gain = 5.9;const double Gain = 5.9; struct Memberstruct Member {{ char Name[20];char Name[20]; int Phone;int Phone; };}; double Fnc(double);double Fnc(double);}}#endif#endif

Page 17: Chap 16    名稱空間

1717/42/42

範例程式 檔案 範例程式 檔案 Second.h Second.h

// Second.h// Second.h#ifndef#ifndef SECOND_H SECOND_H#define #define SECOND_HSECOND_Hnamespacenamespace NS2 NS2 // // 宣告名稱空間 宣告名稱空間 NS2NS2{{ const double Gain = 2.6;const double Gain = 2.6; struct Memberstruct Member {{ int IdNum;int IdNum; char Name[20];char Name[20]; double Profit;double Profit; };}; double Fnc(double);double Fnc(double);}}#endif#endif

Page 18: Chap 16    名稱空間

1818/42/42

範例程式 檔案 範例程式 檔案 FncLib.cpp FncLib.cpp

// FncLib.cpp// FncLib.cpp#include "First.h" #include "First.h" // // 引入引入 NS1NS1 的宣告的宣告#include "Second.h"#include "Second.h" // // 引入引入 NS2NS2 的宣告的宣告// // 定義函數 定義函數 NS1::Fnc()NS1::Fnc()double double NS1NS1::Fnc(double x)::Fnc(double x) {return x * {return x * NS1::NS1::Gain;}Gain;}// // 定義函數 定義函數 NS2::Fnc()NS2::Fnc()double double NS2::NS2::Fnc(double x)Fnc(double x) {return x * {return x * NS2::NS2::Gain;} Gain;}

Page 19: Chap 16    名稱空間

1919/42/42

範例程式 檔案 範例程式 檔案 Array2Fnc.cpp Array2Fnc.cpp

// TestHead.cpp// TestHead.cpp#include <iostream>#include <iostream>using namespace std;using namespace std;#include "First.h" #include "First.h" // // 引入引入 NS1NS1 的宣告的宣告#include "Second.h"#include "Second.h" // // 引入引入 NS2NS2 的宣告的宣告// ----// ---- 主程式主程式 --------------------------------------------int main()int main(){{ NS1NS1::Member Ma={"George Wang", 23246352};::Member Ma={"George Wang", 23246352}; NS2NS2::Member Mb={34,"Peter White", 12.67};::Member Mb={34,"Peter White", 12.67};

Page 20: Chap 16    名稱空間

2020/42/42

cout << "Name of Ma is: "cout << "Name of Ma is: " << Ma.Name << endl;<< Ma.Name << endl; cout << "Name of Mb is: "cout << "Name of Mb is: " << Mb.Name << endl;;<< Mb.Name << endl;; cout << "cout << " NS1:NS1:::Gain is: "Gain is: " << << NS1::NS1::Gain << endl;Gain << endl; cout << "cout << " NS2::Gain is: "NS2::Gain is: " << << NS2::NS2::Gain << endl;Gain << endl; cout << "cout << " NS1::Fnc(2.5) is: "NS1::Fnc(2.5) is: " << << NS1::NS1::Fnc(2.5) << endl;Fnc(2.5) << endl; cout << "cout << " NS2::Fnc(2.5) is: "NS2::Fnc(2.5) is: " << << NS2::NS2::Fnc(2.5) << endl;Fnc(2.5) << endl; return 0;return 0;} }

Page 21: Chap 16    名稱空間

2121/42/42

操作結果 操作結果

Name of Ma is: George WangName of Mb is: Peter WhiteNS1::Gain is: 5.9NS2::Gain is: 2.6NS1::Fnc(2.5) is: 14.75NS2::Fnc(2.5) is: 6.5

Page 22: Chap 16    名稱空間

2222/42/42

使用「使用「 usingusing 指令」以存取名稱空間的成員指令」以存取名稱空間的成員

為了避免在存取時使用諸如為了避免在存取時使用諸如double x = MyNamespace::Ratio;double x = MyNamespace::Ratio;

的冗長成員名稱,可以在程式中加入「的冗長成員名稱,可以在程式中加入「 usinusing g 指令指令」 」 (using directive) (using directive) 加以簡化。例如:加以簡化。例如:

using namespace MyNamespace;using namespace MyNamespace;

……

double x = Ratio;double x = Ratio;

Page 23: Chap 16    名稱空間

2323/42/42

usingusing 指令指令

如果曾經在程式中宣告了名稱空間如果曾經在程式中宣告了名稱空間 MyNamesMyNamespacepace ,則上述,則上述 usingusing 指令相當於在指令的指令相當於在指令的地方加入了下列四個宣告敘述:地方加入了下列四個宣告敘述:

const double Gain = 5.9;const double Gain = 5.9;struct Memberstruct Member{ { char Name[20]; char Name[20]; int Phone; int Phone;

};};double Fnc(double);double Fnc(double);

Page 24: Chap 16    名稱空間

2424/42/42

名稱空間成員的適用範圍 名稱空間成員的適用範圍

局部變數的優先權高於全域變數 局部變數的優先權高於全域變數 (glob(global variables) al variables) 和名稱空間成員。和名稱空間成員。

如果如果 using using 指令或指令或 using using 宣告寫在區宣告寫在區塊之內,則其作用範圍就只有到那個區塊之內,則其作用範圍就只有到那個區塊結尾的地方。塊結尾的地方。

Page 25: Chap 16    名稱空間

2525/42/42

範例程式 檔案 範例程式 檔案 Priority.cpp Priority.cpp

// Priority.cpp// Priority.cpp#include <iostream>#include <iostream>using namespace std;using namespace std;namespacenamespace NSNS // // 宣告名稱空間 宣告名稱空間 NSNS{{ int M = 10; int M = 10; // (1)// (1) float x =1.0, y = 2.0; float x =1.0, y = 2.0; // (2)// (2) char C = 'G'; char C = 'G'; // (3)// (3)}}// ----// ---- 主程式主程式 ----------------------------------------------int main()int main(){{ NSNS::M = 6; ::M = 6; // // 更動更動 (1)(1) 中的中的 MM

Page 26: Chap 16    名稱空間

2626/42/42

{{ float y = 7.5; float y = 7.5; // (4)// (4) 定義局部變數 定義局部變數 yy using namespaceusing namespace NSNS;;// using // using 指令指令 x = 5.6; x = 5.6; // // 更動更動 (2) (2) 中的 中的 xx cout << y; cout << y; // // 輸出輸出 (4) (4) 中的 中的 y (=7.y (=7.

5)5) }} return 0;return 0;}}// C = 'P'; // C = 'P'; 錯誤錯誤 ! ! 此處已無法取用 此處已無法取用 (3) (3) 中的 中的 C C

Page 27: Chap 16    名稱空間

2727/42/42

實例介紹 實例介紹

為了方便對照,我們仍然保留為了方便對照,我們仍然保留 16.216.2 節問題內的節問題內的 First.First.hh ,, FncLib.cppFncLib.cpp 和和 Test.cppTest.cpp 三個檔案的名稱:三個檔案的名稱:

– 檔案檔案 First.hFirst.h 完全沒有改變,這個檔案宣告了名稱空間完全沒有改變,這個檔案宣告了名稱空間 NS1NS1 。。

– 在檔案在檔案 FncLib.cppFncLib.cpp 中,我們只保留了函數中,我們只保留了函數 NS1::Fnc() NS1::Fnc() 的的實作。實作。

– 檔案檔案 Test.cppTest.cpp 也只包括了名稱空間也只包括了名稱空間 NS1NS1 成員的使用。我們成員的使用。我們在這個檔案裹面示範了在這個檔案裹面示範了 usingusing 指令的使用方式。指令的使用方式。

– 本程式在 本程式在 DOS DOS 下的編譯指令仍然為:下的編譯指令仍然為: bcc32 Test FncLibbcc32 Test FncLib

Page 28: Chap 16    名稱空間

2828/42/42

範例程式 檔案 範例程式 檔案 First.h First.h

// First.h// First.h#ifndef FIRST_H#ifndef FIRST_H#define FIRST_H#define FIRST_Hnamespacenamespace NS1 NS1 // // 宣告名稱空間 宣告名稱空間 NS1NS1{{ const double Gain = 5.9;const double Gain = 5.9; struct Memberstruct Member {{

char Name[20];char Name[20];int Phone;int Phone;

};}; double Fnc(double);double Fnc(double);}}#endif#endif

Page 29: Chap 16    名稱空間

2929/42/42

範例程式 檔案 範例程式 檔案 FncLib.cpp FncLib.cpp

// FncLib.cpp// FncLib.cpp

#include "First.h" #include "First.h" // // 引入引入 NS1NS1 的宣告的宣告// // 定義函數 定義函數 NS1::Fnc()NS1::Fnc()

double double NS1NS1::Fnc(double x)::Fnc(double x)

{return x * {return x * NS1::NS1::Gain;} Gain;}

Page 30: Chap 16    名稱空間

3030/42/42

範例程式 檔案 範例程式 檔案 Array2Fnc.cpp Array2Fnc.cpp

// Test.cpp// Test.cpp#include <iostream>#include <iostream>using namespace std;using namespace std;#include "First.h" #include "First.h" // // 引入引入 NS1NS1的宣告的宣告// // 名稱空間 名稱空間 NS1NS1的 的 using using 指令指令using namespaceusing namespace NS1NS1; ; // ----// ----主程式主程式 ----------------------------------------------int main()int main(){{ MemberMember Ma={"George Wang", 23246352}; Ma={"George Wang", 23246352}; MemberMember Mb={"Peter White", 34536767}; Mb={"Peter White", 34536767}; cout << "Name of Ma is "cout << "Name of Ma is " << Ma.Name << endl;<< Ma.Name << endl; cout << "Phone number of Mb is "cout << "Phone number of Mb is " << Mb.Phone << endl;;<< Mb.Phone << endl;; cout << "Gain is: "cout << "Gain is: " << << Gain Gain << endl; << endl; cout << "Fnc(2.5) is: "cout << "Fnc(2.5) is: " << << Fnc(Fnc(2.52.5)) << endl; << endl; return 0;return 0;} }

Page 31: Chap 16    名稱空間

3131/42/42

操作結果 操作結果

Name of Ma is George WangPhone number of Mb is 34536767Gain is: 5.9Fnc(2.5) is: 14.75

Page 32: Chap 16    名稱空間

3232/42/42

使用「使用「 usingusing 宣告」宣告」 (using declaration) (using declaration)

「「 usingusing 宣告」可以選擇性的宣告名稱空間中的成員。例如:宣告」可以選擇性的宣告名稱空間中的成員。例如:namespace NS1namespace NS1 // // 宣告名稱空間 宣告名稱空間 NS1NS1{{ const double Gain = 5.9;const double Gain = 5.9; double A, B, C;double A, B, C; void Fnc1(double);void Fnc1(double); void Fnc2(double);void Fnc2(double); void Fnc3(double);void Fnc3(double); void Fnc4(double);void Fnc4(double);}}namespace NS2namespace NS2 // // 宣告名稱空間 宣告名稱空間 NS2NS2{{ const double Gain = 5.9;const double Gain = 5.9; double A, B, E;double A, B, E; void Fnc3(double);void Fnc3(double); void Fnc4(double);void Fnc4(double); void Fnc5(double);void Fnc5(double); void Fnc6(double);void Fnc6(double);}}

Page 33: Chap 16    名稱空間

3333/42/42

使用「使用「 usingusing 宣告」宣告」

在在 NS1NS1 和和 NS2NS2 這兩個名稱空間中,變數這兩個名稱空間中,變數 AA ,,BB ,和函數,和函數 Fnc3()Fnc3() 、、 Fnc4()Fnc4() 同名。如果同名。如果我們使用以下的我們使用以下的 usingusing 宣告:宣告:

using NS1::A;using NS1::A;using NS1::Fnc2;using NS1::Fnc2;using NS1::Fnc3;using NS1::Fnc3;using NS2::B;using NS2::B;using NS1::Fnc5;using NS1::Fnc5;

就可以選擇性的直接取用就可以選擇性的直接取用 NS1NS1 中的變數中的變數 AA 和和函數函數 Fnc2()Fnc2() 、、 Fnc3()Fnc3() ,以及,以及 NS2NS2 中的變中的變數數 BB 和函數和函數 Fnc5()Fnc5() 。。

Page 34: Chap 16    名稱空間

3434/42/42

標準名稱空間 標準名稱空間

C++ C++ 的標準程式庫 的標準程式庫 (the C++ Standard Libr(the C++ Standard Library) ary) 將所有的程式庫成員都含括在簡稱為將所有的程式庫成員都含括在簡稱為 ststdd 的名稱空間裏面的名稱空間裏面 : : 資料流程式庫 資料流程式庫 <fstream<fstream>, >, 輸出格式程式庫 輸出格式程式庫 <iomanip><iomanip> ,以及計時,以及計時程式庫 程式庫 <ctime> <ctime> 等等都是。等等都是。

能夠以單一名稱空間能夠以單一名稱空間 stdstd 涵蓋這些程式庫的涵蓋這些程式庫的原因,是因為名稱空間具有可以用累積的方原因,是因為名稱空間具有可以用累積的方式逐步加入的特性。式逐步加入的特性。

Page 35: Chap 16    名稱空間

3535/42/42

使用使用 coutcout 和和 endlendl 的三種的三種 usingusing 敘述語法 敘述語法 (1/3)(1/3)

(1)(1) 使用「使用「 usingusing 宣告」宣告」

#include <iostream>#include <iostream>

using std::cout;using std::cout;

using std::endl;using std::endl;

cout << 3.5 << endl;cout << 3.5 << endl;

Page 36: Chap 16    名稱空間

3636/42/42

使用使用 coutcout 和和 endlendl 的三種的三種 usingusing 敘述語法 敘述語法 (2/3)(2/3)

(2)(2) 使用「使用「 usingusing 指令」指令」

#include <iostream>#include <iostream>

using namespace std;using namespace std;

cout << 3.5 << endl; cout << 3.5 << endl;

Page 37: Chap 16    名稱空間

3737/42/42

使用使用 coutcout 和和 endlendl 的三種的三種 usingusing 敘述語法 敘述語法 (3/3)(3/3)

(3)(3) 使用資格修飾子 使用資格修飾子 (qualifier)(qualifier)

#include <iostream>#include <iostream>

std::cout << 3.5 << std::endl;std::cout << 3.5 << std::endl;

Page 38: Chap 16    名稱空間

3838/42/42

未命名的名稱空間 未命名的名稱空間 (unnamed namespac(unnamed namespace) e)

用來限制全域變數 用來限制全域變數 (global variables) (global variables) 的範圍,使的範圍,使它只能在原有檔案內存取,無法跨越到另一個檔案來它只能在原有檔案內存取,無法跨越到另一個檔案來使用。例如:使用。例如:

namespacenamespace{{double GainL=5.6; double GainL=5.6; // GainL // GainL 被限制被限制double FncA(double x) double FncA(double x) // FncA() // FncA() 被限制被限制 {return x*GainL;}{return x*GainL;}}}

在其它檔案中,即使做了在其它檔案中,即使做了extern int GainL;extern int GainL;

的宣告也無法存取不具名的名稱空間中的任何成的宣告也無法存取不具名的名稱空間中的任何成員。員。

Page 39: Chap 16    名稱空間

3939/42/42

範例程式 範例程式  FncLib.cppFncLib.cpp

這個程式區分為這個程式區分為 FncLib.cppFncLib.cpp 和和 Check.cppCheck.cpp兩個檔案。兩個檔案。

在檔案在檔案 FncLib.cppFncLib.cpp 中,我們定義了函數中,我們定義了函數 FncFncB()B() 。。

在檔案在檔案 Check.cppCheck.cpp 中,我們以不具名的名稱中,我們以不具名的名稱空間限制了空間限制了 GainLGainL 和和 FncA() FncA() 只能在此檔案只能在此檔案中使用。中使用。

Page 40: Chap 16    名稱空間

4040/42/42

範例程式 檔案 範例程式 檔案 FncLib.cpp FncLib.cpp

// FncLib.cpp// FncLib.cpp// // 定義函數 定義函數 FncB()FncB()externextern double GainG; double GainG; // // 取用取用 Check.cpp Check.cpp 中的中的 GainGGainG// extern double GainL;// extern double GainL;// // 錯誤錯誤 ! ! 此處已無法取用 此處已無法取用 GainLGainLdouble FncB(double x)double FncB(double x){{ double y = x*GainG;double y = x*GainG; // double y = x*GainL// double y = x*GainL // // 錯誤錯誤 !! 此處已無法取用 此處已無法取用 GainLGainL return y;return y;} }

Page 41: Chap 16    名稱空間

4141/42/42

範例程式 檔案 範例程式 檔案 Check.cpp Check.cpp

// Check.cpp// Check.cpp#include <iostream>#include <iostream>using namespace std;using namespace std;namespacenamespace // // 未命名的名稱空間未命名的名稱空間{{ double GainL=5.6; double GainL=5.6; // GainL // GainL 被限制被限制 double FncA(double x) double FncA(double x) // FncA() // FncA() 被限制被限制 {return x*GainL;}{return x*GainL;}}}double GainG = 3.8; double GainG = 3.8; // // 全域常數 全域常數 GainGGainGdouble FncB(double); double FncB(double); // FncB() // FncB() 的原型的原型// ----// ----主程式主程式 ----------------------------------------------int main()int main(){{ cout << “FncA(5)cout << “FncA(5)是是 : ” : ”

<< FncA(5) << endl; // << FncA(5) << endl; // 呼叫 呼叫 FncA()FncA() cout << “FncB(5)cout << “FncB(5)是是 : ” : ”

<< FncB(5) << endl; // << FncB(5) << endl; // 呼叫 呼叫 FncB()FncB() return 0;return 0;} }

Page 42: Chap 16    名稱空間

4242/42/42

操作結果 操作結果

FncA(5) 是 : 28FncB(5) 是 : 19