c++_引用和指针

1.引用的概念及用法
一个对象的引用就是这个对象的别名,所以对一个对象的进行操作,和直接对这个对象操作的效果是一样的。
如何创建引用?   对象类型 & 引用名 = 对象名;
引用的特点:
  • 引用为一个对象的别名,所以不占内存
  • 引用必须初始化,并且不能为NULL
  • 引用初始化结束后,不能再次改变
代码如下:
#include <iostream>
int main()
{
         int a = 10;
         int *pa = &a;
         int &b = a;
        std::cout << a << std::endl;
        std::cout << *pa << std::endl;
        std::cout << b << std::endl;
        std::cout << &a << std::endl;
        std::cout << pa << std::endl;
        std::cout << &b << std::endl;
        std::cout << sizeof (a) << std::endl;
        std::cout << sizeof (*pa) << std::endl;
        std::cout << sizeof (b) << std::endl;
        system( "pause" );
         return 0;
}

2.引用做参数
我们知道,在交换两个值时不能传值,会产生临时变量,交换的是临时变量的值,实际两个变量的值并没有交换,之前的做法是传指针,现在也可以用传引用的方式交换两个变量的值,函数的参数在调用的时候被初始化,也就是说形参是实参的一个别名,那么操作形参就是对实参的操作
#include <iostream>
void Swap( int & a, int & b) {
         int c = a;
        a = b;
        b = c;
}
int main()
{
         int a = 4;
         int b = 2;
        std::cout << "(a,b) ==> (" << a << "," << b << ")" << std::endl;
        Swap(a, b);
        std::cout << "(a,b) ==> (" << a << "," << b << ")" << std::endl;
        system( "pause" );
         return 0;
}

3.引用做返回值
一个普通的返回值,在函数栈帧销毁是会被保存到一个地方(寄存器,或内存),也就是说会产生一个副本,如果返回一个引用的话就不会产生这个副本,节省资源,提高效率。 但是要注意几点:

  1. 不能返回局部变量的引用。这条可以参照Effective C++[1]的Item 31。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为了"无所指"的引用,程序会进入未知状态。如【例5】中的第2种情况出现编译错误。
  2. 不能返回函数内部new分配的内存的引用。这条可以参照Effective C++[1]的Item 31。虽然不存在局部变量的被动销毁问题,可对于这种情况(返回函数内部new分配内存的引用),又面临其它尴尬局面。例如,被函数返回的引用只是作为一个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由new分配)就无法释放,造成memory leak。
  3. 可以返回类成员的引用,但最好是const。这条原则可以参照Effective C++[1]的Item 30。主要原因是当对象的属性是与某种业务规则(business rule)相关联的时候,其赋值常常与某些其它属性或者对象的状态有关,因此有必要将赋值操作封装在一个业务规则当中。如果其它对象可以获得该属性的非常量引用(或指针),那么对该属性的单纯赋值就会破坏业务规则的完整性。

4.汇编层看引用的特性
#include <iostream>
int main()
{
         int a = 10;
         int *pa = &a;
         int & b = a;
        system( "pause" );
         return 0;
}
    
从汇编的角度看,这个引用中保存的就是a的地址吗,引用就是一个指针变量,为什么底层都是指针,而在语法上不同呢?虽然底层实现是指针,但是在上层对这个指针加以约束,就变得更加安全,在用指针的眼光看待上面的代码,其实也行得通。

5.引用和指针的区别

指针可以初始化也可以不初始化,引用必须初始化,所以引用不会出现NULL
指针可以指向任意地址,而引用在初始化之后就不能再次成为另一个对象的别名,所以传参时不会访问非法内存
指针占4个或8个字节,而引用只是一个别名,不占内存
指针可以自增或者自减(++ --),而对引用来说没有意义,假如b是a的别名,使用b++,实际就是a++
指针有多级指针,而引用只有一级,可以是 int& b = a; 但不可以int &&c = b;后一种方法是错误的

猜你喜欢

转载自blog.csdn.net/luhaowei0066/article/details/80993617