關(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
引用的語法及實例:
- 在C++中可以聲明
// 語法
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ì)
注意:
- C++編譯器在編譯過程中用指針常量作為引用的內(nèi)部實現(xiàn),因此引用所占的空間大小與指針相同拉背;
- 在使用的角度师崎,引用只是一個別名,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)