指针与引用

Posted on 2016-06-01 13:33  洪爵士  阅读(88)  评论(0编辑  收藏  举报

指针做函数参数:

(1)有的情况下我们可能需要在调用函数中分配内存,而在主函数中使用,而针对的指针此时为函数的参数。此时应注意形参与实参的问题,因为在C语言中,形参只是继承了实参的值,是另外一个量形参的改变并不能引起实参的改变。

(2)直接使用形参分配内存的方式显然是错误的,因为实参的值并不会改变。

指针做函数返回值:

(1)使用栈内存返回指针是明显错误的,因为栈内存将在调用结束后自动释放,从而主函数使用该地址空间将很危险。

(2)使用堆内存返回指针是正确的,但是注意可能产生内存泄露问题,在使用完毕后主函数中释放该内存。

引用就是某个目标变量的“别名”(alias),对应用的操作与对变量直接操作效果完全相同。申明一个引用的时候,切记要对其进行初始化。引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,不能再把该引用名作为其他变量名的别名。声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个 别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。不能建立数组的引用。

在给引用初始化的时候,会有一个隐藏的&操作,在给引用赋值的时候,会有一个隐藏的*操作。

综上,在我们使用引用的时候,就把引用当做一个别名,在我们分析学习的时候,就把引用当做是一个常量指针。

注意:引用不是在栈中的,我们是拿不到引用的地址。

引用的意义:

(1)引用作为其它变量的别名而存在,因此在一些场合可以代替指针。

(2)引用相对于指针来说具有更好的可读性和实用性。

C++中引入引用后,可以用引用解决的问题。避免用指针来解决。

切记:不要返回局部变量的引用

引用做函数参数:

(1)传递引用给函数与传递指针的效果是一样的。这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。

(2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。

(3)使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用“*指针变量名”的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参,而引用更容易使用,更清晰。

如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应该使用“常引用”,这点和“常指针”用法一样。

引用做函数返回值:

(1)不能返回局部变量的引用。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为了“无所指“的引用,程序会进入未知状态。

(2)不能返回函数内部new分配的内存的引用。虽然不存在局部变量的被动销毁问题,可对于这种情况(返回函数内部new分配内存的引用),又面临其它尴尬局面。例如,被函数返回的引用只是作为一个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由new分配)就无法释放,造成内存泄露。

(3)可以返回类成员的引用,但最好是 const。主要原因是当对象的属性是与某种业务规则(business rule)相关联的时候,其赋值常常与某些其它属性或者对象的状态有关,因此有必要将赋值操作封装在一个业务规则当中。如果其它对象可以获得该属性的非常量引用(或指针),那么对该属性的单纯赋值就会破坏业务规则的完整性。

(4)流操作符重载返回值申明为“引用“的作用: 流操作符<<和>>,这两个操作符常常希望被连续使用,

引用使用的场景:流操作符<<和>>的返回值、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数。

函数指针

回调函数:当函数指针做为函数的参数,传递给一个被调用函数,被调用函数就可以通过这个指针调用外部的函数,这就形成了回调。

回调函数的优点:

(1)函数的调用和函数的实现有效的分离

(2)类似C++的多态,可扩展。调用后人的代码