經(jīng)扯疲看到書或文章說:引用不占用空間,是不對的键俱。
下面直接用幾個簡單的小實驗證明引用占用的空間與指針一致兰绣。
1、查看 data
段:
#include <iostream>
using namespace std;
int i = 1;
int main(void)
{
cout << "i = " << i << endl;
return 0;
}
在linux環(huán)境下编振,用 g++
編譯后缀辩,用size
命令查看二進制文件:
$ g++ test.cpp
$ size a.out
text data bss dec hex filename
2429 676 280 3385 d39 1.out
下面增加一個引用:
#include <iostream>
using namespace std;
int i = 1;
int &y = i;
int main(void)
{
cout << "i = " << i << endl;
return 0;
}
再看結(jié)果,對比上面踪央,684 - 676 = 8臀玄,很明顯的 data
增加了 8
個字節(jié),因為用的是 64
位環(huán)境畅蹂,指針占用 8
個字節(jié)健无。C++ 編譯器使用常指針作為引用的內(nèi)部實現(xiàn),所以引用所占用的空間大小與指針相同:即 32
位環(huán)境下占用 4
字節(jié)液斜,64
位環(huán)境下占用 8
字節(jié)累贤。
$ g++ test.cpp
$ size a.out
text data bss dec hex filename
2453 684 280 3417 d59 2.out
2叠穆、另一個小實驗,用 sizeof
查看引用類型占用的空間
#include <iostream>
using namespace std;
int i;
struct A
{
int x = i;
};
struct B
{
int &x = i;
};
struct BB
{
int &x = i;
int &y = i;
};
int main(void)
{
cout << "sizeif(A) = " << sizeof(A) << endl;
cout << "sizeif(B) = " << sizeof(B) << endl;
cout << "sizeif(BB) = " << sizeof(BB) << endl;
return 0;
}
運行結(jié)果臼膏,struct A
只有一個 int
型變量硼被,所以是 4
字節(jié),
而 struct B
有 1
個引用渗磅,占 8
字節(jié)嚷硫,剛好是一個指針的大小,
struct BB
有 2
個引用始鱼,所以是 2
個指針的大小仔掸,也就是16
字節(jié):
$ g++ point.cpp
$ ./a.out
sizeif(A) = 4
sizeif(B) = 8
sizeif(BB) = 16
3、直接對比編譯后的匯編文件风响,或可執(zhí)行文件嘉汰,看指針與引用是否存在差異:
#include <iostream>
using namespace std;
int main(void)
{
int i = 1;
int &x = i;
cout << "i = " << i << endl;
cout << "x = " << x << endl;
return 0;
}
#include <iostream>
using namespace std;
int main(void)
{
int i = 1;
int* const x = &i;
cout << "i = " << i << endl;
cout << "x = " << *x << endl;
return 0;
}
g++ -S test.cpp
g++ -S test2.cpp
把這兩個文件編譯生成 test.s 和 test2.s 文件,丟到Beyond Compare
對比状勤,會發(fā)現(xiàn)除了第一行的.file
不同之外鞋怀,其余都相同,畢竟如果我們要輸出__FILE__
持搜,文件名還是不同的密似。
但是如果放在同一個文件里面,修改前后分別編譯成.s
文件葫盼,就完全一致了残腌,或直接編譯成可執(zhí)行文件,用md5sum
命令對比修改前和修改后的值贫导,完全一致抛猫。
4、總結(jié)
所以引用優(yōu)秀的地方不在于是否節(jié)約了內(nèi)存孩灯,
引用是高級語言層面的概念闺金,并未規(guī)定引用的實現(xiàn)方式。
引用的優(yōu)點是引用不會為空峰档,節(jié)省了指針的判空語句败匹;
編寫時不需要寫 *
符號來取內(nèi)容,書寫變得簡單了讥巡。
另外是 指針和引用的自增(++)運算意義也不一樣掀亩;
所以如果業(yè)務要求:定義時不必初始化,可以為NULL
欢顷,要求能改變指向不同的地址槽棍,要求進行指針運算,就使用指針,否則使用引用刹泄。