C++的引用:
变量名的回顾:变量名实质上是一段连续存储空间的别名,是一个标号(门牌号)
程序中通过变量来申请并命名内存空间
通过变量的名字可以使用存储空间
C++中的引用:
#include <stdio.h>
int main()
{
// 定义一个int型变量a,在内存中占4个字节,
// 变量名 a 就代表了这一块内存,或者说 a 是这块内存的别名
int a = 10;
// 定义了一个引用变量 b ,它是 a 的别名,和 a 代表同一块内存空间
// 对 b 的操作 和 对 a 的操作是一样的
int& b = a;
// 改变 b 等于改变了 a
b = 20;
printf ("%d, %d\n", a, b);
// a 与 b 代表同一块内存空间
printf ("%p, %p\n", &a, &b);
return 0;
}
引用的本质:
引用在C++中的内部实现是一个常指针
Type& name Type* const name
C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同。
从使用的角度,引用会让人误会其只是一个别名,没有自己的存储空间。这是C++为了实用性而做出的细节隐藏
当我们使用引用语法的时,我们不去关心编译器引用是怎么做的
当我们分析奇怪的语法现象的时,我们才去考虑c++编译器是怎么做的
指针的引用:
#include "iostream"
using namespace std;
struct Teacher
{
char name[64];
int age ;
};
//在被调用函数 获取资源
int getTeacher(Teacher **p)
{
Teacher *tmp = NULL;
if (p == NULL)
{
return -1;
}
tmp = (Teacher *)malloc(sizeof(Teacher));
if (tmp == NULL)
{
return -2;
}
tmp->age = 33;
// p是实参的地址 *实参的地址 去间接的修改实参的值
*p = tmp;
}
//指针的引用 做函数参数
void getTeacher2(Teacher* &myp)
{
//给myp赋值 相当于给main函数中的pT1赋值
myp = (Teacher *)malloc(sizeof(Teacher));
if (myp == NULL)
{
return;
}
myp->age = 36;
}
void FreeTeacher(Teacher *pT1)
{
if (pT1 == NULL)
{
return ;
}
free(pT1);
}
int main()
{
Teacher *pT1 = NULL;
//1 c语言中的二级指针
getTeacher(&pT1);
cout<< "age:" << pT1->age << endl;
FreeTeacher(pT1);
//2 c++中的引用 (指针的引用)
getTeacher2(pT1);
cout << "age:" << pT1->age << endl;
FreeTeacher(pT1);
cout << "hello..." << endl;
return 0;
}
C++对C函数的拓展:
内联函数:内联函数声明时inline关键字必须和函数定义结合在一起,否则编译器会直接忽略内联请求
C++编译器可以将一个函数进行内联编译
被C++编译器内联编译的函数叫做内联函数
内联函数在最终生成的代码中是没有定义的
C++编译器直接将函数体插入在函数调用的地方
内联函数没有普通函数调用时的额外开销(压栈,跳转,返回
内联函数是一种特殊的函数,具有普通函数的特征(参数检查,返回类型等)
内联函数是对编译器的一种请求,因此编译器可能拒绝这种请求
内联函数由 编译器处理,直接将编译后的函数体插入调用的地方
宏代码片段 由预处理器处理, 进行简单的文本替换,没有任何编译过程
默认参数:
C++中可以在函数声明时为参数提供一个默认值,
当函数调用时没有指定这个参数的值,编译器会自动用默认值代替只有参数列表后面部分的参数才可以提供默认参数值
一旦在一个函数调用中开始使用默认参数值,那么这个参数后的所有参数都必须使用默
函数的重载:
用同一个函数名定义不同的函数
当函数名和不同的参数搭配时函数的含义不同
调用函数重载的准则:
将所有同名函数作为候选者
尝试寻找可行的候选函数:
1 )精确匹配实参
2) 通过默认参数能够匹配实参
3) 通过默认类型转换匹配实参
匹配失败:
1) 最终寻找到的可行候选函数不唯一,则出现二义性,编译失败。
2) 无法匹配所有候选者,函数未定义,编译失败。
函数重载的注意事项:
重载函数在本质上是相互独立的不同函数(静态链编)
重载函数的函数类型是不同的
函数返回值不能作为函数重载的依据
函数重载是由函数名和参数列表决定的。