C++入门篇(2)函数重载、引用

C++入门篇(2)函数重载、引用_第1张图片

目录

1.函数重载

1.1 函数重载的概念

1.2 C++支持函数重载的原理——名字修饰

2.引用

2.1 引用的概念

2.2引用的特性

2.3常引用

2.4使用场景

2.4.1 作参数

2.4.2 作返回值

2.4.3 传值,传引用效率比较

2.4 引用和指针的区别


1.函数重载

1.1 函数重载的概念

函数重载时C++中的一个概念,C++允许在同一作用域中声明几个功能类似的同名函数,这
些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型
不同的问题。

int Add(int x, int y)
{
    cout << x + y << endl;
    return x + y;
}

double Add(double x, double y)
{
    cout << x + y << endl;
    return x + y;
}

比如这种,形参列表中参数类型不同。

void f()
{
    cout << "abcd" << endl;
}

void f(int x)
{
    cout << x << endl;
}

这种一个有形参,一个没有形参也能构成函数重载。

1.2 C++支持函数重载的原理——名字修饰

一段程序的运行要经过预处理,编译,汇编,链接,编译后会生成符号表,链接时就会到符号表中找寻不同的函数,为了区分两个函数名相同的函数,往往会对函数名进行一些修饰,这种修饰在不同的编译器下可能会不一样。

2.引用

2.1 引用的概念

引用就是对一块已经开辟出的空间取一个别名

int a = 1;

这段代码意思是给一个四字节的的空间取了一个名字叫a,我们可以再对这块空间取一个名字

int& b = a;

这样b就是这块空间的别名,对b进行任何操作,也会对 a产生同样的效果。

2.2引用的特性

引用在定义时必须初始化

引用一旦引用一个空间,就不能再引用别的空间

一个变量可以有多个引用

引用和被引用的对象必须是同一类型

2.3常引用

int a = 1;
const int& ra = a;

对引用使用const进行修饰限定,便是常引用,引用可以缩小权限,和平移权限,但不能放大权限。 上面代码就是一段缩小权限。

const int a = 1;
const int& ra = a;

这段代码就是权限平移,引用后可对变量进行的操作与未引用相同。

//const int a = 1;
//int& ra = a;

这就是权限放大了,原变量是只读的,引用后可以修改,当然是不行的。 因此这么写编译器会编译报错。

2.4使用场景

2.4.1 作参数

C语言要实现交换两个变量值的功能必须使用指针

void Swap(int* x, int* y)
{
    int tmp = *x;
    *x = *y;
    *y = tmp;
}

而C++中可以使用引用来传参

void Swap(int& x, int& y)
{
    int tmp = x;
    x = y;
    y = tmp;
}

这样写方便了不少,至少不用麻烦地敲解引用操作符。

2.4.2 作返回值

int& Add(int a, int b)
{
  int c = a + b;
  return c;
}
int main()
{
  int& ret = Add(1, 2);
  Add(3, 4);
  cout << "Add(1, 2) is :"<< ret <

上面的代码就是一个引用为返回值的例子。上面例子中,打印结果可能是随机值,也可能是7,取决于编译器是否会在函数栈帧销毁后清理空间。

为什么会有这种结果呢?不妨来分析一下上面的代码。

上面的Add函数返回了c的引用,而在main函数中的ret接受了返回值后,Add函数的栈帧已经销毁了,这意味着Add函数返回了一个已经被释放的空间的别名,而这块被释放的空间会存放什么值,无从得知。

从上例可以总结出,函数的变量在函数调用结束,函数栈帧销毁后依然能存在,才能使用其引用作为返回值。

2.4.3 传值,传引用效率比较

以值作为返回值返回或作为参数传递时,会生成值的一份临时拷贝,因此传值效率比较低,而传引用直接返回空间别名,或直接用空间别名作为参数传递,效率比值要高。

#include
struct s
{
    int a[10000];
};
void f1(struct s a)
{
    ;
}
void f2(struct s& a)
{
    ;
}
int main()
{
    struct s a;
    size_t begin1 = clock();
    f1(a);
    size_t end1 = clock();
    size_t begin2 = clock();
    f2(a);
    size_t end2 = clock();
    cout << end1 - begin1 << endl;
    cout << end2 - begin2 << endl;
    return 0;
}

可以用这段代码测试下两种传参方式在效率上的差异。

2.4 引用和指针的区别

语法的定义上,引用是指一块空间的别名,而指针在语法定义上是一块空间的地址,这导致在使用时便利程度上有所差异。

但是在底层的实现上,引用也是用指针实现的

int main()
{
    int a = 10;
    int& ra = a;
    ra = 20;
    int* pa = &a;
    *pa = 20;
}

 让我们来看看这段代码的汇编代码

C++入门篇(2)函数重载、引用_第2张图片

可以看到对引用的指针,底层的实现是一致的。

引用对于使用者来说是更方便的。(保准用了引用再也不想用指针)

引用和指针的效率相差无几。

 

 

你可能感兴趣的:(C++基础语法,c++,开发语言)