上一篇帖子我们提到C++的诞生,就是祖师爷为了弥补C语言的一些缺漏。那么我们今天继续来认识C++中C++与C不同的地方(或者说C++的优势所在)。
1.函数重载
所谓重载,简单来讲,就是“一词多义”。
1.1概念
C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数或类型或类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。(本质上就是形参类型)
#include <iostream>
using namespace std;
//1.参数类型不同
int Add(int left,int right)//这个函数传入的两个形参都是int类型
{cout<<"int Add(int left,int right)"<<endl;return left+right;
}
double Add(double left,double right)//这个函数传入的两个性形参都是double类型
{cout<<"double Add(double left,double right)"<<endl;return left+right;
}
//这就是把由于形参的类型不同而构成的函数重载
//2.参数个数不同
void f()
{cout << "f()"<<endl;
}
void f(int a)
{cout <<"f(int a)"<<endl;
}
//这就是由于函数参数个数不同而构成的函数重载
//3.参数类型顺序不同
void f(int a,char b)
{cout << "f(int a,char b)"<<endl;
}
void f(char b,int a)
{cout<<"f(char b,int a)"<<endl;
}
int main()
{Add(10,20);Add(10.1,20.2);f();f(10);f(10,'a');f('a',10);return 0;}
运行结果如下;
注意:1.要能够区分调用歧义和函数重载(即使两个函数构成重载,也可能引发调用歧义=>就是比那一期不知道调用哪个函数,好像谁都可以)
void f()//无参函数
{cout <<"f()"<<endl;
}
void f(int a=10)//全缺省参数
{cout <<"f(innt a)"<<endl;
}
//上面两个函数构成重载,但是仍然引发了歧义
2.不同作用域,可以同名,但无需满足重载
同意作用于,可以同名,但必须满足重载
1.2为什么C++支持函数重载,而C语言不支持呢
因为在进行链接时,
C语言是直接调用函数的名字取查找,故不支持重载
C++是直接用修饰后的函数名字去查找,故支持重载
(所谓名字的修饰规则,就是把形参的类型也加上)
2.引用
2.1概念
引用不是定义一个新的变量,而是给已经存在的变量取别名,他和他引用的变量共用一块内存空间
但是注意,引用类型必须和人引用实体是同种类型的
int a=0;
int &b=a;//b是a的引用,相当于又给a起了个别名
int &c=a;//一个变量可以起多个别名
int &d=b;//也可以给别名起别名
//定义的是a,bcd都是a的别名,它们四个所在地址是一致的
2.2引用特性
1.引用在定义时必须初始化(也就是说到底是谁的别名一开始就要说清)
2.一个变量可以有多个引用
3.引用一旦有一个实体,再不能引用其他实体
int x=0;
int &y=x;
int z=0;
y=z;//注意这一句,在上面y已经是x的别名了,故这一句就不可能再试z的别名了
//在这里就是把z的值赋给y
2.3常引用
权限可以缩小,可以平移,但是不能放大。
//1.
int x=0;
int& y =x;
const int& z=x;//此处是权限的缩小,可行
//2.
const int m=0;
int& n=m;//错误的,因为权限不能放大
const int& n=m;//正确,此处是权限的平移,可行
//3.回顾一下指针
//const 在*之前修饰*p1,p1可以加加,在*后修饰p1,p1就不能动了
const int* p1=&m;
int *p2=p1;//权限的放大,不可以
int *p3=&x;
const int* p4=p3;//权限的缩小,p3可读可写,p4只读
//4.
int& b=10;//错误,
const int& b=10;//正确
//5.类型转换会产生临时变量,临时变量具有常性
double d=12.34;
int i=d;
const int& r=d;
2.4引用和指针的区别
- 语法概念:引用就是一个别名,没有独立空间,与引用实体共用一块空间
- 底层实现:实际是有空间的,因为引用是按照指针方式来实现的
不同点
- 引用概念上定义一个变量的别名,指针存储一个变量地址
- 引用在定义时必须初始化,指针没有要求
- 引用在初始化时引用一个实体后,就不能在引用其他实体,而指针可以在任何时候指向任何一个同类型实体
- 没有NULL引用,但有NULL指针
- 在sizeof中含义不同,引用为引用类型的大小,但指针始终是地址空间所占字节个数(32位环境下占4个字节)
- 引用自加即引用的实体增加1,指针自加即指针向后平移一个类型的大小(以供数组使用)
- 有多级指针,但是没有多级引用
- 访问实体方式不同,引用编译器自己处理,指针需要显示解引用
- 引用比指针使用起来相对更安全