免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
【C++】 命名空間 namespace <iostream> 與 <iostream.h...
【C++】 命名空間 namespace <iostream> 與 <iostream.h> 的區(qū)別
2009-06-02 17:59

本文內(nèi)容:

①命名空間 namespace     基本概念

②由命名空間產(chǎn)生的<iostream> 與 <iostream.h> 的區(qū)別

一 命名空間 namespace     基本概念及使用方法

在C++中,名稱(chēng)(name)可以是符號(hào)常量、變量、宏、函數(shù)、結(jié)構(gòu)、枚舉、類(lèi)和對(duì)象等等。為了避免,在大規(guī)模程序的設(shè)計(jì)中,以及在程序員使用各種各樣的C++庫(kù)時(shí),這些標(biāo)識(shí)符的命名發(fā)生沖突,標(biāo)準(zhǔn)C++引入了關(guān)鍵字namespace(命名空間/名字空間/名稱(chēng)空間/名域),可以更好地控制標(biāo)識(shí)符的作用域。
MFC中并沒(méi)有使用命名空間,但是在.NET框架、MC++和C++/CLI中,都大量使用了命名空間

與命名空間相關(guān)的概念有:

聲明域(declaration region)—— 聲明標(biāo)識(shí)符的區(qū)域。如在函數(shù)外面聲明的全局變量,它的聲明域?yàn)槁暶魉诘奈募T诤瘮?shù)內(nèi)聲明的局部變量,它的聲明域?yàn)槁暶魉诘拇a塊(例如整個(gè)函數(shù)體或整個(gè)復(fù)合語(yǔ)句)。

潛在作用域(potential scope)—— 從聲明點(diǎn)開(kāi)始,到聲明域的末尾的區(qū)域。因?yàn)镃++采用的是先聲明后使用的原則,所以在聲明點(diǎn)之前的聲明域中,標(biāo)識(shí)符是不能用的。即,標(biāo)識(shí)符的潛在作用域,一般會(huì)小于其聲明域。

可見(jiàn)性(scope)—— 標(biāo)識(shí)符對(duì)程序可見(jiàn)的范圍。標(biāo)識(shí)符在其潛在作用域內(nèi),并非在任何地方都是可見(jiàn)的。例如,局部變量可以屏蔽全局變量、嵌套層次中的內(nèi)層變量可以屏蔽外層變量,從而被屏蔽的全局或外層變量在其倍屏蔽的區(qū)域內(nèi)是不可見(jiàn)的。所以,一個(gè)標(biāo)識(shí)符的作用域可能小于其潛在作用域。

命名空間

命名空間(namespace)是一種描述邏輯分組的機(jī)制,可以將按某些標(biāo)準(zhǔn)在邏輯上屬于同一個(gè)集團(tuán)的聲明放在同一個(gè)命名空間中。

原來(lái)C++標(biāo)識(shí)符的作用域分成三級(jí):代碼塊({……},如復(fù)合語(yǔ)句和函數(shù)體)、類(lèi)和全局?,F(xiàn)在,在其中的類(lèi)和全局之間,標(biāo)準(zhǔn)C++又添加了命名空間這一個(gè)作用域級(jí)別。

命名空間可以是全局的,也可以位于另一個(gè)命名空間之中,但是不能位于類(lèi)和代碼塊中。所以,在命名空間中聲明的名稱(chēng)(標(biāo)識(shí)符),默認(rèn)具有外部鏈接特性(除非它引用了常量)。

在所有命名空間之外,還存在一個(gè)全局命名空間,它對(duì)應(yīng)于文件級(jí)的聲明域。因此,在命名空間機(jī)制中,原來(lái)的全局變量,現(xiàn)在被認(rèn)為位于全局命名空間中。

標(biāo)準(zhǔn)C++庫(kù)(不包括標(biāo)準(zhǔn)C庫(kù))中所包含的所有內(nèi)容(包括常量、變量、結(jié)構(gòu)、類(lèi)和函數(shù)等)都被定義在命名空間std(standard標(biāo)準(zhǔn))中了。

2)定義命名空間
有兩種形式的命名空間——有名的和無(wú)名的。

命名空間的定義格式為:(取自C++標(biāo)準(zhǔn)文檔)

named-namespace-definition:

       namespace identifier { namespace-body }

unnamed-namespace-definition:

       namespace { namespace-body }

namespace-body:

       declaration-seqopt

即:(自己翻譯并改寫(xiě)的)

有名的命名空間:

       namespace 命名空間名 {

              聲明序列可選

       }

無(wú)名的命名空間:

       namespace {

              聲明序列可選

       }

命名空間的成員,是在命名空間定義中的花括號(hào)內(nèi)聲明了的名稱(chēng)??梢栽诿臻g的定義內(nèi),定義命名空間的成員(內(nèi)部定義)。也可以只在命名空間的定義內(nèi)聲明成員,而在命名空間的定義之外,定義命名空間的成員(外部定義)。

命名空間成員的外部定義的格式為:

命名空間名::成員名 ……

例如:

// out.h

namespace Outer {                                     // 命名空間Outer的定義

       int i;                                                     // 命名空間Outer的成員i的內(nèi)部定義

       namespace Inner {                              //命名空間Inner的內(nèi)部定義

              void f() { i++; }                                // 命名空間Inner的成員f()的內(nèi)部定義,其中的i為Outer::i

              int i;

              void g() { i++; }                             // 命名空間Inner的成員g()的內(nèi)部定義,其中的i為Inner::i

              void h();                                      // 命名空間Inner的成員h()的聲明

       }

       void f();                                             // 命名空間Outer的成員f()的聲明

       // namespace Inner2;                           // 錯(cuò)誤,不能聲明子命名空間

}

void Outer::f() {i--;}                                    // 命名空間Outer的成員f()的外部定義

void Outer::Inner::h() {i--;}                         // 命名空間Inner的成員h()的外部定義

// namespace Outer::Inner2 {/*……*/}        // 錯(cuò)誤,不能在外部定義子命名空間

 

注意:

不能在命名空間的定義中聲明(另一個(gè)嵌套的)子命名空間,只能在命名空間的定義中定義子命名空間。

也不能直接使用“命名空間名::成員名 ……”定義方式,為命名空間添加新成員,而必須先在命名空間的定義中添加新成員的聲明。

另外,命名空間是開(kāi)放的,即可以隨時(shí)把新的成員名稱(chēng)加入到已有的命名空間之中去。方法是,多次聲明和定義同一命名空間,每次添加自己的新成員和名稱(chēng)。例如:

namespace A {

       int i;

       void f();

} // 現(xiàn)在A有成員i和f()

namespace A {

       int j;

       void g();

} // 現(xiàn)在A有成員i、f()、j和g()

還可以用多種方法,來(lái)組合現(xiàn)有的命名空間,讓它們?yōu)槲宜?。例如?/font>

namespace My_lib {

       using namespace His_string;

       using namespace Her_vector;

       using Your_list::List;

       void my_f(String &, List &);

}

……

using namespace My_lib;

……

Vector<String> vs[5];

List<int> li[10];

my_f(vs[2], li[5]);

3)使用命名空間

作用域解析運(yùn)算符::

對(duì)命名空間中成員的引用,需要使用命名空間的作用域解析運(yùn)算符::。例如:

// out1.cpp

#include "out.h"

#include <iostream>

int main ( ) {

       Outer::i = 0;

       Outer::f(); // Outer::i = -1;

       Outer::Inner::f(); // Outer::i = 0;

       Outer::Inner::i = 0;

       Outer::Inner::g(); // Inner::i = 1;

       Outer::Inner::h(); // Inner::i = 0;

       std::cout << "Hello, World!" << std::endl;

       std::cout << "Outer::i = " << Outer::i << ", Inner::i = " << Outer::Inner::i << std::endl;

}

using指令using namespace

為了省去每次調(diào)用Inner成員和標(biāo)準(zhǔn)庫(kù)的函數(shù)和對(duì)象時(shí),都要添加Outer::Inner::和sta::的麻煩,可以使用標(biāo)準(zhǔn)C++的using編譯指令來(lái)簡(jiǎn)化對(duì)命名空間中的名稱(chēng)的使用。格式為:

using namespace 命名空間名[::命名空間名……];

在這條語(yǔ)句之后,就可以直接使用該命名空間中的標(biāo)識(shí)符,而不必寫(xiě)前面的命名空間定位部分。因?yàn)?strong>using指令,使所指定的整個(gè)命名空間中的所有成員都直接可用。例如:

// out2.cpp

#include "out.h"

#include <iostream>

// using namespace Outer; // 編譯錯(cuò)誤,因?yàn)樽兞縤和函數(shù)f()有名稱(chēng)沖突

using namespace Outer::Inner;

using namespace std;

int main ( ) {

       Outer::i = 0;

       Outer::f();                // Outer::i = -1;

       f();                         // Inner::f(),Outer::i = 0;

       i = 0;                       // Inner::i

       g();                         // Inner::g(),Inner::i = 1;

       h();                         // Inner::h(),Inner::i = 0;

       cout << "Hello, World!" << endl;

       cout << "Outer::i = " << Outer::i << ", Inner::i = " << i << endl;

}

又例如:(.NET框架)

using namespace System::Drawing::Imaging;

using namespace System::Window::Forms::Design::Behavior;

using聲明(using)

除了可以使用using編譯指令(組合關(guān)鍵字using namespace)外,還可以使用using聲明來(lái)簡(jiǎn)化對(duì)命名空間中的名稱(chēng)的使用。格式為:

using 命名空間名::[命名空間名::……]成員名;

注意,關(guān)鍵字using后面并沒(méi)有跟關(guān)鍵字namespace,而且最后必須為命名空間的成員名(而在using編譯指令的最后,必須為命名空間名)。

與using指令不同的是,using聲明只是把命名空間的特定成員的名稱(chēng),添加該聲明所在的區(qū)域中,使得該成員可以不需要采用,(多級(jí))命名空間的作用域解析運(yùn)算符來(lái)定位,而直接被使用。但是該命名空間的其他成員,仍然需要作用域解析運(yùn)算符來(lái)定位。例如:

// out3.cpp

#include "out.h"

#include <iostream>

using namespace Outer;                                              // 這是 using命令注意,此處無(wú)::Inner

using namespace std;

// using Inner::f;                                                            // 編譯錯(cuò)誤,因?yàn)楹瘮?shù)f()有名稱(chēng)沖突

using Inner::g;                                                      // using 聲明此處省去Outer::,是因?yàn)镺uter已經(jīng)被前面的using指令作用過(guò)了

using Inner::h;

int main ( ) {

       i = 0;                                                          // Outer::i

       f();                                                              // Outer::f(),Outer::i = -1;

       Inner::f();                                                    // Outer::i = 0;

       Inner::i = 0;

       g();                                                            // Inner::g(),Inner::i = 1;

       h();                                                            // Inner::h(),Inner::i = 0;

       cout << "Hello, World!" << endl;

       cout << "Outer::i = " << i << ", Inner::i = " << Inner::i << endl;

}

using指令與using聲明的比較:

 

可見(jiàn),using編譯指令和using聲明,都可以簡(jiǎn)化對(duì)命名空間中名稱(chēng)的訪問(wèn)。

using指令使用后,可以一勞永逸,對(duì)整個(gè)命名空間的所有成員都有效,非常方便。而using聲明,則必須對(duì)命名空間的不同成員名稱(chēng),一個(gè)一個(gè)地去聲明,非常麻煩。

但是,一般來(lái)說(shuō),使用using聲明會(huì)更安全。因?yàn)?,using聲明只導(dǎo)入指定的名稱(chēng),如果該名稱(chēng)與局部名稱(chēng)發(fā)生沖突,編譯器會(huì)報(bào)錯(cuò)。而using指令導(dǎo)入整個(gè)命名空間中的所有成員的名稱(chēng),包括那些可能根本用不到的名稱(chēng),如果其中有名稱(chēng)與局部名稱(chēng)發(fā)生沖突,則編譯器并不會(huì)發(fā)出任何警告信息,而只是用局部名去自動(dòng)覆蓋命名空間中的同名成員。特別是命名空間的開(kāi)放性,使得一個(gè)命名空間的成員,可能分散在多個(gè)地方,程程序員難以準(zhǔn)確知道,別人到底為該命名空間添加了哪些名稱(chēng)。雖然使用命名空間的方法,有多種可供選擇。但是不能貪圖方便,一味使用using 指令,這樣就完全背離了設(shè)計(jì)命名空間的初衷,也失去了命名空間應(yīng)該具有的防止名稱(chēng)沖突的功能。

一般情況下,對(duì)偶爾使用的命名空間成員,應(yīng)該使用命名空間的作用域解析運(yùn)算符來(lái)直接給名稱(chēng)定位。而對(duì)一個(gè)大命名空間中的經(jīng)常要使用的少數(shù)幾個(gè)成員,提倡使用using聲明,而不應(yīng)該使用using編譯指令。只有需要反復(fù)使用同一個(gè)命名空間的許多數(shù)成員時(shí),使用using編譯指令,才被認(rèn)為是可取的。

例如,如果一個(gè)程序(如上面的outi.cpp)只使用一兩次cout,而且也不使用std命名空間中的其他成員,則可以使用命名空間的作用域解析運(yùn)算符來(lái)直接定位。如:

#include <iostream>

……

std::cout << "Hello, World!" << std::endl;

std::cout << "Outer::i = " << Outer::i << ", Inner::i = " << Outer::Inner::i << std::endl;

又例如,如果一個(gè)程序要反復(fù)使用std命名空間中的cin、cout和cerr(如上面的outi.cpp),而不怎么使用其他std命名空間中的其他成員,則應(yīng)該使用using 聲明而不是using指令。如:

#include <iostream>

……

using std::cout;

cout << "Hello, World!" << endl;

cout << "Outer::i = " << Outer::i << ", Inner::i = " << Outer::Inner::i << endl;

4)命名空間的名稱(chēng)

命名空間別名

標(biāo)準(zhǔn)C++引入命名空間,主要是為了避免成員的名稱(chēng)沖突。若果用戶都給自己的命名空間取簡(jiǎn)短的名稱(chēng),那么這些(往往同是全局級(jí)的)命名空間本身,也可能發(fā)生名稱(chēng)沖突。如果為了避免沖突,而為命名空間取很長(zhǎng)的名稱(chēng),則使用起來(lái)就會(huì)不方便。這是一個(gè)典型的兩難問(wèn)題。

標(biāo)準(zhǔn)C++為此提供了一種解決方案——命名空間別名,格式為:

namespace 別名 = 命名空間名;

例如:(AT&T美國(guó)電話電報(bào)公司)

namespace American_Telephone_and_Telegraph { // 命名空間名太長(zhǎng)

       class String {

              String(const char*);

              // ……

       }

}

American_Telephone_and_Telegraph::String s1 // 使用不方便

= new American_Telephone_and_Telegraph::String("Grieg");

namespace ATT = American_Telephone_and_Telegraph; // 定義別名

ATT::String s2 = new ATT::String("Bush"); // 使用方便

ATT::String s3 = new ATT::String("Nielsen");

 

<!--[if !supportLists]-->l     <!--[endif]-->無(wú)名命名空間

標(biāo)準(zhǔn)C++引入命名空間,除了可以避免成員的名稱(chēng)發(fā)生沖突之外,還可以使代碼保持局部性,從而保護(hù)代碼不被他人非法使用。如果你的目的主要是后者,而且又為替命名空間取一個(gè)好聽(tīng)、有意義、且與別人的命名空間不重名的名稱(chēng)而煩惱的話,標(biāo)準(zhǔn)C++還允許你定義一個(gè)無(wú)名命名空間:可以在當(dāng)前編譯單元中(無(wú)名命名空間之外),直接使用無(wú)名命名空間中的成員名稱(chēng),但是在當(dāng)前編譯單元之外,它又是不可見(jiàn)的。

無(wú)名命名空間的定義格式為:

namespace {

       聲明序列可選

}

實(shí)際上,上面的定義等價(jià)于:(標(biāo)準(zhǔn)C++中有一個(gè)隱含的使用指令)

namespace $$$ {

       聲明序列可選

}

using namespace $$$;

例如:

namespace {

       int i;

       void f() {/*……*/}

}

int main() {

       i = 0;                                                    // 可直接使用無(wú)名命名空間中的成員i

       f();                                                       // 可直接使用無(wú)名命名空間中的成員f()

}


參考:http://www.91linux.com/html/article/program/cpp/20080220/9737_3.html

二 <iostream>和<iostream.h> 的區(qū)別

<iostream>和<iostream.h>是不一樣,前者沒(méi)有后綴,實(shí)際上,在你的編譯器include文件夾里面可以看到,二者是兩個(gè)文件,打開(kāi)文件就會(huì)發(fā)現(xiàn),里面的代碼是不一樣的。

后綴為.h的頭文件c++標(biāo)準(zhǔn)已經(jīng)明確提出不支持了,早些的實(shí)現(xiàn)將標(biāo)準(zhǔn)庫(kù)功能定義在全局空間里,聲明在帶.h后綴的頭文件里,c++標(biāo)準(zhǔn)為了和C區(qū)別開(kāi),也為了正確使用命名空間,規(guī)定頭文件不使用后綴.h。

因此,當(dāng)使用<iostream.h>時(shí),相當(dāng)于在c中調(diào)用庫(kù)函數(shù),使用的是全局命名空間,也就是早期的c++實(shí)現(xiàn);當(dāng)使用<iostream>的時(shí)候,該頭文件沒(méi)有定義全局命名空間,必須使用namespace std;這樣才能正確使用cout。

所謂namespace,是指標(biāo)識(shí)符的各種可見(jiàn)范圍。

C++標(biāo)準(zhǔn)程序庫(kù)中的所有標(biāo)識(shí)符都被定義于一個(gè)名為std的namespace中。

由于namespace的概念,使用C++標(biāo)準(zhǔn)程序庫(kù)的任何標(biāo)識(shí)符時(shí),可以有三種選擇:

1、直接指定標(biāo)識(shí)符。例如std::ostream而不是ostream。完整語(yǔ)句如下:

std::cout << std::hex << 3.4 << std::endl;

2、使用using關(guān)鍵字。

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

以上程序可以寫(xiě)成

cout << std::hex << 3.4 << endl;

3、最方便的就是使用using namespace std;

例如:

#include <iostream>
#include <sstream>
#include <string>
using namespace std;
這樣命名空間std內(nèi)定義的所有標(biāo)識(shí)符都有效(曝光)。就好像它們被聲明為全局變量一樣。那么以上語(yǔ)句可以如下寫(xiě):

cout << hex << 3.4 << endl;

因?yàn)闃?biāo)準(zhǔn)庫(kù)非常的龐大,所程序員在選擇的類(lèi)的名稱(chēng)或函數(shù)名時(shí)就很有可能和標(biāo)準(zhǔn)庫(kù)中的某個(gè)名字相同。所以為了避免這種情況所造成的名字沖突,就把標(biāo)準(zhǔn)庫(kù)中的一切都被放在名字空間std中。但這又會(huì)帶來(lái)了一個(gè)新問(wèn)題。無(wú)數(shù)原有的C++代碼都依賴(lài)于使用了多年的偽標(biāo)準(zhǔn)庫(kù)中的功能,他們都是在全局空間下的。  

         所以就有了<iostream.h>和<iostream>等等這樣的頭文件,一個(gè)是為了兼容以前的C++代碼,一個(gè)是為了支持新的標(biāo)準(zhǔn)。

命名空間std封裝的是標(biāo)準(zhǔn)程序庫(kù)的名稱(chēng),標(biāo)準(zhǔn)程序庫(kù)為了和以前的頭文件區(qū)別,一般不加".h"

 

 

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
01、C++命名空間(namespace)詳解
#include<iostream>和#include<iostream.h>的區(qū)別
linux C++ 第一個(gè)程序
c++小程序出錯(cuò)解決方法
using namespace std詳解(收集整理) - mainsun -- IT博客...
命名空間std,using namespace std (轉(zhuǎn)載)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服