引用和函数重载

引用

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;
}

函数重载

函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能
类似的同名函数,这些同名函数的形参列表(参数个数、类型、顺序)必须
不同,而与返回值类型无关,常用来处理实现功能类似数据类型不同的问题。

例:

int Add(int left, int right)
{
return left+right;
}
double Add(double left, double right)
{
return left+right;
}
long Add(long left, long rigjt)
{
return left+right;
}
int main()
{
Add(10, 20);         
Add(10.0, 20.0);
Add(10L, 20L);       //传的参数不同,调用的函数也会不同
return 0;
}

面试题
1. C语言中为什么不能支持函数重载?

如果有多个.c文件,注意 在链接之前各文件都是独立向下进行的,各文件之间没有交集。
所以支持重载问题就出在链接这个阶段上,c语言在链接的时候根据函数名找要调用的函数,而c++而是根据函数名和参数类型来寻找要调用的函数(函数名修饰规则)

2. C++中函数重载底层是怎么处理的? C++中能否将一个函数按照C的风格来编译?
参考如下:
https://blog.csdn.net/eson_15/article/details/56483926

下面两个函数能形成函数重载吗?有问题吗或者什么情况下会出问题?

void FunTest(int a = 10)
{
cout<<"void FunTest(int)"<<endl;
}
void FunTest(int a)
{
cout<<"void FunTest(int)"<<endl;
}

答:不能。
两个函数,一个带缺省值,一个不带;区别在于:前者在调用时,如未传参,则会使用默认的10作为参数,即它可以不传参,也可以传参;
而后者在调用时就必须传参。所以当传参时,系统就不知道要要调用哪个函数了,就会出问题。

猜你喜欢

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