经常看到书或文章说:引用不占用空间,是不对的。
下面直接用几个简单的小实验证明引用占用的空间与指针一致。
1、查看 data
段:
#include <iostream>
using namespace std;
int i = 1;
int main(void)
{
cout << "i = " << i << endl;
return 0;
}
在linux环境下,用 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;
}
再看结果,对比上面,684 - 676 = 8,很明显的 data
增加了 8
个字节,因为用的是 64
位环境,指针占用 8
个字节。C++ 编译器使用常指针作为引用的内部实现,所以引用所占用的空间大小与指针相同:即 32
位环境下占用 4
字节,64
位环境下占用 8
字节。
$ 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;
}
运行结果,struct A
只有一个 int
型变量,所以是 4
字节,
而 struct B
有 1
个引用,占 8
字节,刚好是一个指针的大小,
struct BB
有 2
个引用,所以是 2
个指针的大小,也就是16
字节:
$ g++ point.cpp
$ ./a.out
sizeif(A) = 4
sizeif(B) = 8
sizeif(BB) = 16
3、直接对比编译后的汇编文件,或可执行文件,看指针与引用是否存在差异:
#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
对比,会发现除了第一行的.file
不同之外,其余都相同,毕竟如果我们要输出__FILE__
,文件名还是不同的。
但是如果放在同一个文件里面,修改前后分别编译成.s
文件,就完全一致了,或直接编译成可执行文件,用md5sum
命令对比修改前和修改后的值,完全一致。
4、总结
所以引用优秀的地方不在于是否节约了内存,
引用是高级语言层面的概念,并未规定引用的实现方式。
引用的优点是引用不会为空,节省了指针的判空语句;
编写时不需要写 *
符号来取内容,书写变得简单了。
另外是 指针和引用的自增(++)运算意义也不一样;
所以如果业务要求:定义时不必初始化,可以为NULL
,要求能改变指向不同的地址,要求进行指针运算,就使用指针,否则使用引用。
网友评论