指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变;
而引用是一个别名,它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化,
而且其引用的对象在其整个生命周期中是不能被改变的(自始至终只能依附于同一个变量).
引用必须初始化. 但是用对象的地址初始化引用是错误的,我们可以定义一个指针引用.
int ival = 1092;
int &re = ival; //ok
int &re2 = &ival; //error
总结一下指针和引用的相同点和不同点:
★相同点:
●都是地址的概念;
指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名。
★不同点:
●指针是一个实体,而引用仅是个别名;
●引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终”,指针可以“见异思迁”;
●引用没有const,指针有const,const的指针不可变;
●引用不能为空,指针可以为空;
●“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof指针”得到的是指针本身的大小;
●指针和引用的自增(++)运算意义不一样;
●引用是类型安全的,而指针不是 (引用比指针多了类型检查
在任何情况下都不能用指向空值的引用
不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针的要高。因为在使用引用之前不需要测试它的合法性。
voidprintDouble(const double& rd)
{
cout<< rd; // 不需要测试rd,它肯定指向一个double值
}
相反,指针则应该总是被测试,防止其为空:
voidprintDouble(const double *pd)
{
if(pd) { // 检查是否为NULL
cout<< *pd;
}
}
指针与引用的另一个重要的不同是指针可以被重新赋值以指向另一个不同的对象。但是引用则总是指向在初始化时被指定的对象,以后不能改变。
strings1("Nancy");
strings2("Clancy");
string&rs = s1; //rs 引用 s1
string*ps = &s1; // ps 指向 s1
rs= s2; // rs 仍旧引用s1,但是 s1的值现在是"Clancy"
ps= &s2; // ps 现在指向 s2;s1 没有改变
(1)总的来说,在以下情况下你应该使用指针,一是你考虑到存在不指向任何对象的可能(在这种情况下,你能够设置指针为空),二是你需要能够在不同的时刻指向不同的对象(在这种情况下,你能改变指针的指向)。如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么你应该使用引用
(2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所 占空间都好。
(3)使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"*指针变量名"的形式进 行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。而引用更容易使用,更清晰。
如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用
const既可以放到类型前又可以放到类型后面,但放类型后比较容易理解
const引用的语义到底是什么?
const引用表示,试图通过此引用去(间接)改变其引用的对象的值时,编译器会报错!这并意味着,此引用所引用的对象也因此变成const类型了。我们仍然可以改变其指向对象的值,只是不通过引用
下面是一个简单的例子:
1 #include<iostream>
2 using namespace std;
4 int main()
5 {
6 intval = 1024;
7 constint &ir = val;
9 val++;
10 //ir++;
12 cout<< val << " " << ir << endl;
14 return 0;
15 }
其中第10行,如果我们通过ir来改变val的值,编译时会出错。但是我们仍然可以通过val直接改变其值(第9行)
//可以从内存空间上去思考,传参无外乎拷贝和引用,拷贝分拷贝地址和拷贝值
俺的帖子
http://topic.csdn.net/u/20111122/13/f0855ec7-c0b4-457a-a99d-d7c74aaeb6f0.html
应该能有点用
//总结一点:凡是指针,值传递,绝对发生拷贝,不容置疑;指针传递拷贝地址,值传递拷贝的是值的副本,
本质原因是因为变量内存空间不同。
引用是别名,传递引用是不会拷贝的