指针和引用到底什么时候用?通常情况下是根据不同场景来选择是使用指针还是引用,选择适合场景需求的才是一个优秀程序员所应具备的能力。
我们在做项目开发时,也会考虑到一个维护成本,如果你的前任是一个“高手”,写的代码你基本看不懂,无外乎两点原因,一是前任的问题,二是你自己的问题。所以平时养成一个好的习惯,修炼好内功自然能够以不变应万变。
一、概念
指针指向的是一块内存,它的内容是所指内存的地址;引用是模块内存的别名。
二、指针和引用的区别
1、指针是一个实体,而引用是一个别名;
2、引用使用时无需解引用(*),指针使用时需要解引用;
3、引用只能在定义时被初始化一次,之后不可变,引用“从一而终”,而指针可变;
4、引用不能为空,指针可以为空;
5、“sizeof(引用)”得到的是所指向变量(对象)的大小,而“sizeof(指针)”得到的是指针本身的大小;
6、指针和引用的自增(++)运算意义不一样。
以上列举的是比较常见的一些区别,有兴趣的朋友们也可以继续总结区别,大家一起讨论交流。
三、指针和引用使用场景
1、如果使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时应该把变量声明为指针,因为这样可以赋空值给该变量;
2、如果变量肯定指向一个对象,例如设计中不允许变量为空,这时就可以把变量声明为引用;
3、重载操作符时应当返回引用(主要是为了减少不必要开销,引用效率高)。
四、举例说明
1、例子1
char *p = NULL;//设置指针为空值
char &r = *p;//让引用指向空值 X
//这样做非常有害,执行结果是不确定的
string &rs;//错误,引用必须初始化 X
string s("simon");
string &rs = s;//正确,rs指向s
string *p;//未初始化的指针,虽说能编译通过,但是存在风险
2、例子2
不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针的要高。因为在使用之前不需要测试它的合法性。
void printInt(const int& ri)
{
cout<<ri<<endl;//不需要测试ri,它肯定指向一个int值
}
//vs
void printInt(const int *pi)
{
if(pi)
{
//检查pi是否为NULL
cout<<*pi<endl;
}
}
3、例子3
重载操作符时,应当返回引用。原因是防止返回对象的时候调用拷贝构造函数和析构函数导致不必要的开销,降低赋值运算符的效率。
如果用“值传递”的方式,虽然功能正确,但由于需要把*this拷贝到外部存储单元之中,增加了不必要的开销,比如会降低赋值函数的效率等。
4、例子4
指针传递
#include <iostream>
using namespace std;
void fun(int *p)
{
*p = (*p) + 10;
}
void main()
{
int n = 0;
fun(&n);
cout << n << endl;
return;
}
引用传递
#include <iostream>
using namespace std;
void fun(int &ri)
{
ri = ri + 10;
}
void main()
{
int n = 0;
fun(n);
cout << n << endl;
return;
}