1、指针有自己的一块空间,而引用只是一个别名
指针有自己的内存,引用的内存就是引用的对象的对存
#include <iostream>
using namespace std;
int main()
{
int data = 1;
int* a = &data;
int& b = data;
cout << "address of a = " << &a << endl;
cout << "value of a = " << a << endl;
cout << "address of b = " << &b << endl;
system("pause");
return 0;
}
address of a = 00CFF9CC
value of a = 00CFF9D8
address of b = 00CFF9D8
请按任意键继续. . .
2、使用sizeof看一个指针大小是4,而引用则是被引用的对象的大小
#include <iostream>
using namespace std;
int main()
{
double data = 1.0;
double* a = &data;
double& b = data;
cout << "size of a = " << sizeof(a) << endl;
cout << "size of b = " << sizeof(b) << endl;
system("pause");
return 0;
}
size of a = 4
size of b = 8
请按任意键继续. . .
3、指针可以被初始化为NULL,而引用必须被初始化且必须是一个已有对象的引用
#include <iostream>
using namespace std;
int main()
{
double data = 1.0;
double* a = nullptr;
double& b = nullptr;
system("pause");
return 0;
}
4、作为参数传递时,指针需要被解引用才可以对对象进行操作,而直接对引用的修改都是会改变引用所指向的对象
#include <iostream>
using namespace std;
void ptrChange(int * data)
{
*data = 50;
}
void referenceChange(int & data)
{
data = 100;
}
int main()
{
int data = 3;
cout << "before change data = " << data << endl;
ptrChange(&data);
cout << "after ptrChange data = " << data << endl;
referenceChange(data);
cout << "after referenceChange data = " << data << endl;
system("pause");
return 0;
}
before change data = 3
after ptrChange data = 50
after referenceChange data = 100
请按任意键继续. . .
5、指针在使用中可以指向其它对象,但是引用只能是一个对象的引用,不能被改变
#include <iostream>
using namespace std;
int main()
{
int dataA = 3;
int dataB = 4;
int* ptr = &dataA;
ptr = &dataB;
int& ref = dataA;
ref = dataB;//虽然有的编译器能够编译过去,但其实只是赋值
cout <<"dataA = "<< dataA << endl;
ref = 100;//这里改变的依旧是dataA的值
cout << "dataA = " << dataA << endl;
cout << "dataB = " << dataB << endl;
system("pause");
return 0;
}
dataA = 4
dataA = 100
dataB = 4
请按任意键继续. . .
6、指针的指针有,引用的引用无
#include <iostream>
using namespace std;
int main()
{
int dataA = 3;
int* ptr = &dataA;
int** pptr = &ptr;
int& ref = dataA;
int&& rref = ref;
system("pause");
return 0;
}
7、指针可以使多级指针,引用只能是一级引用
8、指针和引用使用++运算符的意义不一样
#include <iostream>
using namespace std;
int main()
{
int dataA = 3;
int* ptr = &dataA;
cout << "ptr = " << ptr<< endl;
cout << "++ptr = " << ++ptr<< endl;
int& ref = dataA;
cout << "ref = " << ref << endl;
cout << "++ref = " <<++ref<< endl;
system("pause");
return 0;
}
ptr = 0113FD60
++ptr = 0113FD64
ref = 3
++ref = 4
请按任意键继续. . .
9、如果返回动态内存分配的对象和内存,必须使用指针,引用可能会引起内存泄漏
因为临时变量会因为函数的结束,而被释放,就无法释放申请的内存。
当然并不一定会报错
#include <iostream>
using namespace std;
int* ptrApplyMemory()
{
int * a = new int;
cout << "memory address in ptrApplyMemory = " << a << endl;
return a;
}
int* & refApplyMemory()
{
int * a = new int;
cout << "memory address in refApplyMemory = " << a << endl;
return a;//此时函数结束,a的生命周期结束,理论上a的引用也就无效。
}
int main()
{
int *ptr = ptrApplyMemory();
cout << "ptr = " << ptr << endl;
delete ptr;
int* & ref = refApplyMemory();//理论上引用ref代表的对象已经被释放
cout <<"ref = "<< ref << endl;
delete ref;
system("pause");
return 0;
}
memory address in ptrApplyMemory = 00A4AA38
ptr = 00A4AA38
memory address in refApplyMemory = 00A4AA38
ref = 00A4AA38
总结
除了使用方法的差异意外,引用似乎像是弱化版的指针,是不是有点像指针常量呢?当然了,当你知道需要指向某个东西,而且绝不对改变其指向时,引用是一个不错的选择。
其实要是说,引用底层封装的指针,是指针的变化版本也可以。