函数重载原理与引用——7.17c++学习记录

文章目录


前言

今天讲函数重载原理和引用的相关知识。


一、函数名修饰规则

我们都知道,c语言是不允许函数名同名的,c++则可以通过函数重载实现,而c++函数重载原理就是函数名修饰规则

c语言:

在生成可执行程序的过程中,c语言把不同的函数名放进符号表里,把函数名当做地址,在两个函数名相同时,编译器无法分别,所以c语言不支持函数重载

c++:

而c++有函数名修饰规则,将原本相同的名字根据其参数的类型、个数、顺序而改变,然后放入符号表,可以区别,这也是返回值不同不能构成函数重载的原因之一,即函数名修饰规则与返回值无关

在我们眼中相同的函数名,经过编译器的处理之后,已经成了不同的名字

但函数名修饰规则每个编译器不同,具体的不必掌握

那么如果函数名修饰规则跟返回值有关,那返回值不同能不能构成函数重载?

答案也是不能,因为调用时是不写返回值的,只有返回值不同的话就无法区别调用的是哪个了

二、引用

1.概念

引用 不是新定义一个变量,而 是给已存在变量取了一个别名 ,编译器不会为引用变量开辟内存空
间,它和它引用的变量 共用同一块内存空间。
类型 & 引用变量名 ( 对象名 ) = 引用实体;
int a = 0;
int& b = a; // 引用

引用就像是起外号,这个新定义的变量名就是它的外号,既然是外号,那么外号和本来的名字指的就都是同一个人

稍微提一下,引用不开辟空间只是理论上的,但在实际上并不如此,它的底层是指针

2.特性

1. 引用在 定义时必须初始化
2. 一个变量可以有多个引用
3. 引用一旦引用一个实体,再不能引用其他实体
int main()
{
	// int& b; // 引用在定义时必须初始化
	int a = 0;
 //像是一个人可以有好几个外号
	int& b = a;
	int& c = a;
	int& d = b;

	int x = 1;
	// 赋值, 引用一旦引用一个实体,再不能引用其他实体
	b = x;

	return 0;
}

最后一条即一旦是一个变量的别名,就不能是其他变量的别名。

像是蛋哥是王斌的外号,那么蛋哥这个外号只属于他自己,别人不能再被叫蛋哥了

3.应用

1.传引用传参

引用在传指针的情况下会方便很多,可以不用传指针或者二级指针变成一级指针

因为传的是它的别名,可以直接修改别名来达到修改它的目的,而不必传地址解引用来改变

 //c语言二级指针的玩法
//为了修改一级指针只能使用二级指针
void PushBack(ListNode** pphead, int x)
{
    //......
}

// CPP,引用的玩法
void PushBack(ListNode*& phead, int x)//传一级指针的引用,就可以直接修改一级指针
}
   //......
}

 传引用传参(任何时候都可以用)
 1、提高效率
 2、输出型参数(形参的修改,影响的实参)

2.传引用返回

 //C的接口设计
 //读取第i个位置的值
int SLAT(struct SeqList* ps, int i)
{
	assert(i < ps->size);
	// ...
	return ps->a[i];
}
 //修改第i个位置的值
void SLModify(struct SeqList* ps, int i, int x)
{
	assert(i < ps->size);

	// ...
	ps->a[i] = x;
}

 //CPP接口设计
// 读 or 修改第i个位置的值
int& SLAT(struct SeqList& ps, int i)
{
	assert(i < ps.size);
	// ...
	return (ps.a[i]);
}

使用c语言时必须写两个函数来分别完成读和写,因为返回第i个位置的值时,返回的是ps.a[i]的值,是常量,不能修改

使用c++时返回ps.a[i]的引用,那么就不止能读,还能改了

int& Add(int a, int b)
{
    int c = a + b;
    return c;
}
注意: 如果函数返回时,出了函数作用域,如果返回对象还在 ( 还没还给系统 ) ,则可以使用
引用返回,如果已经还给系统了,则必须使用传值返回。

像是上面的情况,返回了c的引用,但是c出了函数作用域已经被销毁了,那就出现了一种类似野指针的情况,指向的变量已经没了,但是你还指向它,就会出现问题

这个并不是局部变量就一定不能返回引用,还是要看出了作用域销毁不销毁

这个灵活看待,主要看出了作用域是否销毁,而不是看是不是局部变量

 传引用返回(出了函数作用域对象还在才可以用)
 1、提高效率
 2、修改返回对象

4.与const相关知识

1.基本概念 

在引用的过程中
 权限可以平移
 权限可以缩小
 权限不能放大

const int a = 0;

// 权限的放大
// int& b = a;//a被const修饰不能改变,b此时不能作为a的别名,
// b一旦成为a的别名,改变b就会影响a,这样就成了权限的放大

//int b = a; 可以的,因为这里是赋值拷贝,b修改不影响a

// 权限的平移
const int& c = a;

// 权限的缩小
//本来x是完全不受限制的
int x = 0;
const int& y = x;//现在y作为x的别名,不能修改,权限缩小
//但是x仍旧不受限制

权限的缩小像是原本叫齐天大圣,可以上天入地没有限制,当改名孙悟空后,就要老实点,多了限制

2.举例

类型转换时会先生成一个临时变量,然后再由临时变量把值给d,而临时变量具有常性,d此时不能作为临时变量的别名,d一旦成为临时变量的别名,改变d就会影响临时变量,这样就成了权限的放大,只有加了const,使d不能改变,才能作为临时变量的别名

下面的也是类似情况

稍微提一下,当本该销毁的变量加了引用修饰后,就会延长生命周期,随ret一起销毁


总结

今天讲了函数重载的原理函数名修饰规则,并解释了为什么c语言不能函数重载,还有引用的一些知识,包括它的基本概念和应用,还有与const相关的部分

  • 22
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

north-shaddock

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值