5_引用的本質(zhì)分析

關(guān)鍵詞: 引用的意義贬蛙、 const引用

1. 引用的意義

  • 引用作為變量別名而存在,因此在一些場合可以代替指針
  • 引用相對于指針來說具有更好的可讀性實用性

編程說明:swap函數(shù)通過指針實現(xiàn)和通過引用對比

#include <stdio.h>

#define LOG_INT(i) printf("%s = %d\n", #i, i);

void swap_pointer(int* a, int* b)
{
    int temp = *a;
    *a = *b;
    *b = temp;

}

void swap_cite(int& a, int& b)
{
    int temp = a;
    a = b;
    b = temp;
}

int main(int argc, char* argv[])
{
    int i = 1;
    int j = 2;
    int n = 3;
    int m = 4;
    
    LOG_INT(i);
    LOG_INT(j);

    swap_pointer(&i, &j);
    
    LOG_INT(i);
    LOG_INT(j);
    
    LOG_INT(n);
    LOG_INT(m);
    
    swap_cite(n, m);
    
    LOG_INT(n);
    LOG_INT(m);

    return 0;
}

輸出結(jié)果:

i = 1
j = 2
i = 2
j = 1
n = 3
m = 4
n = 4
m = 3

2. 特殊的引用

  • const引用
    • 在C++中可以聲明 const引用差导;
    • const引用讓變量擁有只讀屬性鲫忍;
    • const引用的語法及實例:
// 語法
const Type& name = var;

// 實例
int a = 4;
const int& b = a;
int* p = (int*)&b;

b = 5;  //  Error, 只讀變量

*p = 5; // ok, 修改變量a的值
  • 在一般情況下舰始,引用不可以是常量的別名第焰,但是可以使用常量對const引用進(jìn)行初始化,C++編譯器會為常量值分配空間上枕,并將引用名作為這段空間的別名
#include <stdio.h>

#define LOG_INT(i) printf("%s = %d\n", #i, i);
#define LOG_POINTER(p) printf("%s = %p\n", #p, p);

int main(int argc, char* argv[])
{
    const int& b = 1;   // ok咐熙,生成一個只讀變量

    int* p = (int*) &b;
    
    LOG_INT(b);
    LOG_POINTER(&b);
    LOG_POINTER(p);

//  b = 5   // Error,只讀變量,不能直接賦值

    *p = 5; // ok辨萍,修改了const只讀變量中的值
    
    LOG_INT(b); 
    LOG_POINTER(&b);
    LOG_POINTER(p);

    return 0;
}

輸出結(jié)果:

b = 1
&b = 0xbf843514
p = 0xbf843514
b = 5
&b = 0xbf843514
p = 0xbf843514

結(jié)論:使用常量對const引用初始化后將生成一個只讀變量棋恼。

編程說明:引用的特殊意義

#include <stdio.h>

#define LOG_STR(str) printf("%s\n", str);
#define LOG_INT(i) printf("%s = %d\n", #i, i);

void Example()
{
    LOG_STR("Example:");

    int a = 4;
    const int& b = a;
    int* p = (int*)&b;

    *p = 5;

    LOG_INT(a);
    LOG_INT(b);
}

void Demo()
{
    LOG_STR("Demo:");

    const int& c = 1;
    int* p = (int*)&c;

    *p = 5;

    LOG_INT(c);
}

int main(int argc, char* argv[])
{
    Example();
    
    LOG_STR("");

    Demo();

    return 0;
}

輸出結(jié)果:

Example:
a = 5
b = 5

Demo:
c = 5

總結(jié): 在C++中想要得到一個只讀變量,可以通過const引用來實現(xiàn)锈玉。

3. 思考:引用有自己的存儲空間嗎爪飘?

編程說明:引用的思考

#include <stdio.h>

#define LOG_SIZEOF(type) printf("sizeof(%s) = %d\n", #type, sizeof(type));

struct TRef
{
    char& r;
};

int main(int argc, char* argv[])
{
    char c = 'c';
    char& rc = c;
    TRef ref = {c};

    LOG_SIZEOF(char&);  // 1
    LOG_SIZEOF(rc);     // 1
    LOG_SIZEOF(TRef);
    LOG_SIZEOF(ref.r);  // 1

    return 0;
}

輸出結(jié)果:

sizeof(char&) = 1
sizeof(rc) = 1
sizeof(TRef) = 4
sizeof(ref.r) = 1

4. 引用的本質(zhì)

  • 引用在C++中的內(nèi)部實現(xiàn)是一個指針常量
    引用的本質(zhì)

注意:

  1. C++編譯器在編譯過程中用指針常量作為引用的內(nèi)部實現(xiàn),因此引用所占的空間大小與指針相同拉背;
  2. 在使用的角度师崎,引用只是一個別名,C++為了實用性而隱藏了引用的存儲空間這一細(xì)節(jié)去团。
    編程說明:引用的存儲空間
#include <stdio.h>

#define LOG_SIZEOF(type) printf("sizeof(%s) = %d\n", #type, sizeof(type));
#define LOG_POINTER(p) printf("%s = %p\n", #p, p);

struct TRef
{
    char* before;
    char& r;
    char* after;
};

int main(int argc, char* argv[])
{
    char a = 'a';
    char& b = a;
    char c = 'c';
    
    TRef r = {&a, b, &c};

    LOG_SIZEOF(r);  
    LOG_SIZEOF(r.before);       
    LOG_SIZEOF(r.after);
    LOG_POINTER(&r.before);
    LOG_POINTER(&r.after);  

    return 0;
}

輸出結(jié)果:

sizeof(r) = 12
sizeof(r.before) = 4
sizeof(r.after) = 4
&r.before = 0xbfd17384
&r.after = 0xbfd1738c

5. 引用的意義

  • C++中的引用旨在在大多數(shù)的情況下代替指針
    • 功能性:可以滿足多數(shù)需要使用指針的場合
    • 安全性:可以避開由于指針操作不當(dāng)而帶來的內(nèi)存錯誤
    • 操作性:簡單易用抡诞,又不失功能強(qiáng)大

注意:不可以返回局部變量的引用。

6. 小結(jié)

  • 引用作為變量別名而存在土陪,旨在代替指針
  • const引用可以使得變量具有只讀屬性
  • 引用在編譯器內(nèi)部使用指針常量實現(xiàn)
  • 引用的最終本質(zhì)為指針
  • 引用可以盡可能的避開內(nèi)存錯誤

聲明:此文章僅是本人在學(xué)習(xí)狄泰學(xué)院《C++深度解析教程》所做的筆記,文章中包含狄泰軟件資料內(nèi)容肴熏,一切版權(quán)歸狄泰軟件所有鬼雀!
實驗環(huán)境:gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蛙吏,隨后出現(xiàn)的幾起案子源哩,更是在濱河造成了極大的恐慌,老刑警劉巖鸦做,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件励烦,死亡現(xiàn)場離奇詭異,居然都是意外死亡泼诱,警方通過查閱死者的電腦和手機(jī)坛掠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人屉栓,你說我怎么就攤上這事舷蒲。” “怎么了友多?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵牲平,是天一觀的道長。 經(jīng)常有香客問我域滥,道長纵柿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任启绰,我火速辦了婚禮藐窄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘酬土。我一直安慰自己荆忍,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布撤缴。 她就那樣靜靜地躺著刹枉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪屈呕。 梳的紋絲不亂的頭發(fā)上微宝,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機(jī)與錄音虎眨,去河邊找鬼蟋软。 笑死,一個胖子當(dāng)著我的面吹牛嗽桩,可吹牛的內(nèi)容都是我干的岳守。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼碌冶,長吁一口氣:“原來是場噩夢啊……” “哼湿痢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起扑庞,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤譬重,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后罐氨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體臀规,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年栅隐,在試婚紗的時候發(fā)現(xiàn)自己被綠了塔嬉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片玩徊。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖邑遏,靈堂內(nèi)的尸體忽然破棺而出佣赖,到底是詐尸還是另有隱情,我是刑警寧澤记盒,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布憎蛤,位于F島的核電站,受9級特大地震影響纪吮,放射性物質(zhì)發(fā)生泄漏俩檬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一碾盟、第九天 我趴在偏房一處隱蔽的房頂上張望棚辽。 院中可真熱鬧,春花似錦冰肴、人聲如沸屈藐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽联逻。三九已至,卻和暖如春检痰,著一層夾襖步出監(jiān)牢的瞬間包归,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工铅歼, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留公壤,地道東北人。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓椎椰,卻偏偏與公主長得像厦幅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子俭识,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,864評論 2 354

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