函数重载和引用

引用

1.概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会
为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。

使用:
类型&引用变量名(对象名)=引用实体;

void TestRef()
{
int a = 10;
//ra是a的引用
int& ra = a;
//所以输出a和ra结果是一样的
printf("%p\n", &a);
printf("%p\n", &ra);
}
输出结果:10
              10

注意:上述类型必须和引用实体是同种类型的

2.引用特性

a)引用在定义时必须初始化
b)一个变量可以有多个引用
c)引用一旦引用一个实体,再不能引用其他实体

void TestRef()
{
int a = 10;
int b= 20;
// int& ra;   // a (该条语句编译时会出错)
int& ra = a;   //b
int& rra = a;
//int& ra= b;  //c
printf("%p %p %p\n", &a, &ra, &rra);
}

3.常引用

void TestConstRef()
{
const int a = 10;
//int& ra = a; //  该语句编译时会出错, a 为常量
const int& ra = a;
// int& b = 10; //  该语句编译时会出错, b 为常量
const int& b = 10;
double d = 12.34;
//int& rd = d; //  该语句编译时会出错,类型不同
const int& rd = d;
}

问题:数组可以引用吗?如果可以,怎么实现??

答:可以。
例:     int arr[10]={0};
     int (&a)[10]=arr;   //a是数组arr的引用

4.使用场景
①作为函数形参

void Swap(int& left, int& right)
{
   int temp = left;
   left = right;
   right = temp
}

②作为函数返回值

int& TestRefReturn(int& a)
{
a += 10;
return a;
}

注意:不能返回栈空间上的引用,因为函数返回后,栈空间就销毁了,此时返回的引用仍可以访问之前的栈空间,这是不合理的。
例:

int& Add(int a, int b)
{
int c = a + b;
return c;
}
int main()
{
int& ret = Add(10, 20);      //Add函数返回的是栈上空间的引用,
                            //由ret接收;所以函数运行结束后,
                            //ret还是可以访问到栈上的空间,结果是30          
Add(100, 200);             //再次执行Add函数后,ret可以查看到结果是300
}

5.引用和指针的区别
相同点:

底层的实现方式相同,都是按照指针的方式来实现的

这里写图片描述

不同点:

引用在定义时必须初始化,指针没有要求
一旦一个引用被初始化为指向一个对象,就不能再指向其他对
象,而指针可以在任何时候指向任何一个同类型对象
没有NULL引用,但有NULL指针
在sizeof中含义不同:引用结果为引用类型的大小,但指针始
终是地址*空间所占字节个数
引用自加改变变量的内容,指针自加改变了指针指向
有多级指针,但是没有多级引用
指针需要手动寻址,引用通过编译器实现寻址
引用比指针使用起来相对更安全?

思考下面的代码:有问题么?

void Swap(int& left, int& right)   //right是对*p的引用,而*p==NULL
{
int temp = left;
left = right;       //在底层中,会对right解引用,此时就会出错
right = temp;
}
int main()
{
int a = 10;
int* p = NULL;
Swap(a, *p);     // *p==NULL
return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_33279168/article/details/80659538