C++命名空間和作用域限定符, since 2020-11-15

(2020.11.15 Sun)

C++命名空間namespace(ns)

命名空間的引入是為了避免變量或函數(shù)重名的問題睡毒。

C++中的名稱(name)可以是符號常量力惯、變量舌厨、宏刨疼、函數(shù)专缠、結(jié)構(gòu)狰挡、枚等捂龄。大規(guī)模程序設(shè)計(jì)中可能會出現(xiàn)標(biāo)識符的命名發(fā)生沖突。解決辦法是將變量定義在一個(gè)不同名字的命名空間中加叁。

命名空間有兩種:有名與無名跺讯,他們的定義格式如下

namespace 命名空間名 
{聲明序列}
//有名
namespace 
{聲明序列}
//無名

命名空間的成員可以在命名空間的定義內(nèi)為其命名(內(nèi)部定義),也可在命名空間外定義成員(外部定義)殉农。但是不能再外部定義子命名空間刀脏。

namespace outer
{
    int i;
    namespace inner  //子命名空間
    {
        void f() {i++;}
    }
    void f();
}
void outer::f() //在命名空間外部定義成員
{
    i++;
}
  • 命名空間只能定義在頭文件中head file
  • 命名空間開放,可以隨時(shí)更新加入新的成員
//前面已經(jīng)定義了outer
namespace outer // 給命名空間outer加入新的成員
{
    int k;
    void g() {
        printf('g');
    }
}
  • 引用命名空間中的成員超凳,使用作用域運(yùn)算符::
outer::k = 1;  //引用命名空間的成員并賦值時(shí)不需要指定數(shù)據(jù)類型
  • 在預(yù)編譯部分中會出現(xiàn)include <iostream>和include <iostream.h>愈污。在新的C++標(biāo)準(zhǔn)中,生成頭文件的方法僅僅是將現(xiàn)有頭文件名中的.h去掉轮傍。以前的C++頭文件名.h會繼續(xù)支持暂雹,但頭文件的內(nèi)容不在命名空間std中。新的頭文件和舊文件相同创夜,但是頭文件的內(nèi)容在命名空間std(一個(gè)類)中杭跪。因此調(diào)用std,即using namespace std前需要做預(yù)處理驰吓,即#include <iostream>涧尿,才可以使用std內(nèi)的函數(shù)等內(nèi)容。如果不調(diào)用std檬贰,not using namespace std姑廉,則在調(diào)用cin/cout時(shí)需要使用std::cin/cout。
#include <iostream>
using namespace std; //using編譯指令
int main() {
    cout << 'this is  a C++ p.' << endl;
    return 0;
}
//or
#include <iostream>
int main() {
    std::cout <<' this is also a C++ p.' << endl;
    return 0;
}
//或只使用命名空間的某個(gè)成員
#include <iostream>
using outer::g; //using聲明翁涤,針對命名空間中名稱的使用
void main () {
    g(); //調(diào)用outer的g成員
}
  • 上面的例子中有using namespace outer和using outer::g兩種用法桥言,前一種稱為using編譯指令,后一種稱為using聲明葵礼。聲明只把ns中特定成員的名稱添加到所在的區(qū)域号阿,使得該成員可以不需要采用命名空間的作用域解析運(yùn)算符來定位,而直接被使用鸳粉。但是使用using聲明更安全扔涧,因其只會導(dǎo)入指定的名稱。如果該名稱與局部名稱發(fā)生沖突赁严,則編譯器會報(bào)錯(cuò)扰柠。而using指令導(dǎo)入整個(gè)ns中所有成員的名稱粉铐,如果其中有名稱與局部名稱發(fā)生沖突,編譯器不會報(bào)錯(cuò)卤档,只是用局部名稱自動覆蓋ns中的同名成員蝙泼。當(dāng)需要反復(fù)使用一個(gè)ns中的多個(gè)函數(shù)時(shí),使用using編譯指令劝枣;當(dāng)只需要使用一個(gè)ns中的特定幾個(gè)函數(shù)時(shí)汤踏,建議使用ns聲明。

(2020.11.17 Tues)

命名空間和類的區(qū)別

一般程序的開發(fā)都由多人完成舔腾,為防止不同模塊的類和函數(shù)重名溪胶,采用命名空間來區(qū)分避免混淆。

只要兩個(gè)類在不同的命名空間中稳诚,他們就可以擁有相同的類名稱哗脖。把類封裝進(jìn)命名空間的優(yōu)勢在于方便調(diào)用甚至其他應(yīng)用程序的調(diào)用。

#include <iostream>
using namespace std;
namespace s1
{
    class S_Class
        {
        public:
            void show() 
            {
                cout << '調(diào)用命名空間S1中類S_Class的函數(shù)show().' << endl;
            }
        };
}
namespace s2
{
    class S_Class
    {
    public:
        void show()
        {
            cout << '調(diào)用命名空間s2的類S_Class的函數(shù)show()' << endl;
        }
    };
}
int main() {
    s1::S_Class x; //聲明一個(gè)s1中類S_Class的實(shí)例x
    x.show(); //調(diào)用類實(shí)例x中的show()扳还,輸出結(jié)果
    s2::S_Class y; //聲明一個(gè)s2中類S_Class的實(shí)例y
    y.show(); //調(diào)用類實(shí)例y中的show()才避,輸出結(jié)果
    return 0;
}

作用域限定符Scope resolution operator ::

在三種情況中使用作用域限定符

  • 命名空間的使用過程中,使用::來引用指定命名空間中的成員氨距。另一種引用方法是使用using指令桑逝。
  • 在不同作用域內(nèi)聲明的變量可以重名,但如果局部變量和全局變量重名俏让,在局部變量的作用域內(nèi)可以使用::來引用全局變量楞遏。
#include <iostream>
using namespace std;
int x = 100; //定義全局變量
int main ()
{  
    int x = 150;
    cout << '全局變量x=' << ::x << endl; //輸出全局變量
    cout << '局部變量x=' << x << endl; //輸出局部變量
    ::x = 750;
    cout << '全局變量x=' << ::x << endl; //輸出全局變量
    cout << '局部變量x=' << x << endl; //輸出局部變量
    return 0;
}

另外,::只能用來訪問全局變量首昔,不能訪問一個(gè)在語句塊外生命的同名局部變量寡喝。下面是一個(gè)錯(cuò)誤的使用方式。

//這是一個(gè)錯(cuò)誤的使用方式
void main() {
    int x = 11; //x是局部變量
    {
        int x = 22;
        ::x = 33; //錯(cuò)誤的修改方式沙廉,因x也是局部變量
    }
}
  • 在類外定義類成員函數(shù)時(shí)拘荡,需要使用scope resolution operator。比如聲明一個(gè)類A撬陵,里面聲明了一個(gè)成員函數(shù)void fun();,如果類中沒有給出該成員定義网缝,在類外定義該成員時(shí)巨税,要寫成void A::fun(),表示函數(shù)fun()是類A的成員函數(shù)粉臊。
#include <iostream>
#include <string.h>
class cbook
{
    private:
        char * m_pczname;
        int m_npages;
        int m_nedition;
    public:
        void getbookname(char *pname);
        int getbookedition();
    private:
        void setbookname(char * pname);
        void settotalpages(int npages);
    public:
        cbook();
}; //定義一個(gè)類和結(jié)構(gòu)體的結(jié)尾處的大括號后面有個(gè)分號
void cbook::getbookname(char * pname)
{
    strcpy(pname, m_pczname); //定義成員函數(shù)
}
int cbook::getbookedition()
{
    return m_nedition; //成員函數(shù)中引用類成員變量草添,直接寫名字,不需要加self
}
void cbook::setbookname(char * pname)
{
    if (m_pczname != 0)
        delete[] p_pczname;
    m_pczname = new char[strlen(pname)+1]; //重新分配存儲空間
    strcpy(m_pczname,pname); //復(fù)制字符串
}
void cbook::settotalpages(int npages)
{
    m_npages = npages; //成員函數(shù)中引用類成員變量扼仲,直接寫名字远寸,不需要加self
}
void main ()
{
    cbook op1; //聲明該類的對象
    int i;
    i = op1.getbookedition();
    cout << i << endl;
}

這里注意到抄淑,類說明的程序內(nèi)容較多,應(yīng)該放在獨(dú)立的文件中驰后。例如cbook的類說明可以放在頭文件xxx.h中肆资,類的定義放在以.cpp為擴(kuò)展名的文件中,稱為類的實(shí)現(xiàn)文件灶芝。在文件開始部分應(yīng)該用include將類說明文件包含進(jìn)來(類實(shí)現(xiàn)可以不include?)

Reference

1 劉蕾編著郑原,21天學(xué)通C++,中國工信出版集團(tuán)夜涕,電子工業(yè)出版社
2 聚慕課教育研發(fā)中心編著犯犁,C++從入門到項(xiàng)目實(shí)踐(超值版),清華大學(xué)出版社

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末女器,一起剝皮案震驚了整個(gè)濱河市酸役,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌驾胆,老刑警劉巖簇捍,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異俏拱,居然都是意外死亡暑塑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門锅必,熙熙樓的掌柜王于貴愁眉苦臉地迎上來事格,“玉大人,你說我怎么就攤上這事搞隐【杂蓿” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵劣纲,是天一觀的道長逢捺。 經(jīng)常有香客問我,道長癞季,這世上最難降的妖魔是什么劫瞳? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮绷柒,結(jié)果婚禮上志于,老公的妹妹穿的比我還像新娘。我一直安慰自己废睦,他們只是感情好伺绽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般奈应。 火紅的嫁衣襯著肌膚如雪澜掩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天杖挣,我揣著相機(jī)與錄音肩榕,去河邊找鬼。 笑死程梦,一個(gè)胖子當(dāng)著我的面吹牛点把,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播屿附,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼郎逃,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了挺份?” 一聲冷哼從身側(cè)響起褒翰,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎匀泊,沒想到半個(gè)月后优训,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡各聘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年揣非,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片躲因。...
    茶點(diǎn)故事閱讀 40,137評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡早敬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出大脉,到底是詐尸還是另有隱情搞监,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布镰矿,位于F島的核電站琐驴,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏秤标。R本人自食惡果不足惜绝淡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望抛杨。 院中可真熱鬧够委,春花似錦、人聲如沸怖现。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屈嗤。三九已至潘拨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間饶号,已是汗流浹背铁追。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留茫船,地道東北人琅束。 一個(gè)月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像算谈,于是被迫代替她去往敵國和親涩禀。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容