C++?引用和指針的區(qū)別對比分析
在 C++ 中,指針(Pointer)和引用(Reference)都用于間接訪問變量,但是它們在語法和語義上都有顯著的差異。指針是一個變量,它可以保存另一個變量的內(nèi)存地址;引用是另一個變量的別名,由編譯器進行處理,使用時與使用原變量無異。
指針和引用使用的一些差異如下:
初始化
指針:可以先定義后賦值,也可以指向不同的對象。
int a = 10, b = 20; int* p = &a; p = &b; // 改變指向
引用:必須在定義時就進行初始化,綁定到一個特定的對象,并且不能綁定到其他的對象。
int a = 10, b = 20; int& r = a; r = b; // 修改的是 a 的值,而不是重新綁定,等價于 a=b
可空性
指針:可以被定義為 nullptr,表示不指向任何對象。
引用:必須綁定有效對象,不能為 null,否則會產(chǎn)生為定義的行為。
內(nèi)存占用
指針:由于存儲的是內(nèi)存地址,因此需要占用內(nèi)存空間,一般為 32 bit 或 64 bit。
引用:語義上不占用內(nèi)存空間,實際可能由編譯器實現(xiàn)為一個隱藏指針。
這里我們參考一篇博客: C++ 中指針和引用的區(qū)別。
參考以下使用引用和指針實現(xiàn)的 swap 函數(shù)。
void swap(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}引用版本 swap() 函數(shù)的匯編代碼如下:
# void swap(int &a, int &b)
__Z4swapRiS_: ## @_Z4swapRiS_
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movq %rdi, -8(%rbp) # 傳入的第一個參數(shù)存放到%rbp-8 (應(yīng)該是采用的寄存器傳參,而不是常見的壓棧)
movq %rsi, -16(%rbp) # 第二個參數(shù) 存放到 %rbp-16
movq -8(%rbp), %rsi # 第一個參數(shù)賦給 rsi
movl (%rsi), %eax # 以第一個參數(shù)為地址取出值賦給eax,取出*a暫存寄存器
movl %eax, -20(%rbp) # temp = a
movq -16(%rbp), %rsi # 將第二個參數(shù)重復上面的
movl (%rsi), %eax
movq -8(%rbp), %rsi
movl %eax, (%rsi) # a = b
movl -20(%rbp), %eax # eax = temp
movq -16(%rbp), %rsi
movl %eax, (%rsi) # b = temp
popq %rbp
retq
.cfi_endproc
## -- End function指針版本 swap() 函數(shù)的匯編代碼如下:
# void swap(int *a, int *b)
__Z4swapPiS_: ## @_Z4swapPiS_
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movq %rdi, -8(%rbp)
movq %rsi, -16(%rbp)
movq -8(%rbp), %rsi
movl (%rsi), %eax
movl %eax, -20(%rbp)
movq -16(%rbp), %rsi
movl (%rsi), %eax
movq -8(%rbp), %rsi
movl %eax, (%rsi)
movl -20(%rbp), %eax
movq -16(%rbp), %rsi
movl %eax, (%rsi)
popq %rbp
retq
.cfi_endproc
## -- End function可以看到,兩個函數(shù)的匯編代碼幾乎完全一致。引用所賦的初值也就是綁定對象的內(nèi)存地址,訪問和修改對象內(nèi)容也是通過這個內(nèi)存地址完成的。
既然引用和指針的底層實現(xiàn)機制幾乎沒有區(qū)別,那么為什么我們需要使用引用呢?我認為有以下兩點:
- 便捷性:能夠讓使用者使用引用與使用對象本身一致,由編譯器自動進行取地址、解引用的操作。
- 安全性:引用必須初始化,且不能更換綁定,避免了懸空指針和野指針的問題,這在接口設(shè)計中更可靠,要求必須傳入合法的對象。
到此這篇關(guān)于C++ 引用和指針的區(qū)別對比分析的文章就介紹到這了,更多相關(guān)C++ 引用和指針內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言之把數(shù)組名作函數(shù)參數(shù)的四種情況說明
這篇文章主要介紹了C語言之把數(shù)組名作函數(shù)參數(shù)的四種情況說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07
C語言實現(xiàn)直角坐標轉(zhuǎn)換為極坐標的方法
這篇文章主要介紹了C語言實現(xiàn)直角坐標轉(zhuǎn)換為極坐標的方法,涉及C語言進行三角函數(shù)與數(shù)值運算相關(guān)操作技巧,需要的朋友可以參考下2017-09-09
NDK 數(shù)據(jù)結(jié)構(gòu)之隊列與棧等的實現(xiàn)
這篇文章主要介紹了NDK 數(shù)據(jù)結(jié)構(gòu)之隊列與棧等的實現(xiàn)的相關(guān)資料,希望通過本文大家能理解掌握這部分內(nèi)容,需要的朋友可以參考下2017-10-10

