重载函数相关

生命可以随心所欲,但不能随波逐流。
                                     —— 《猫的报恩》

C++中的重载函数

  • 什么是函数重载

      同一声明域中的函数名相同,参数列表不同(指参数的个数、类型或者顺序)的函数,即通过函数的参数表而唯一标识并且来区分函数的一种特殊的函数。重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。

函数的重载的规则:

  • 函数名称必须相同。
  • 参数列表必须不同(个数不同、类型不同、参数排列顺序不同等)。
  • 函数的返回类型可以相同也可以不相同。
  • 仅仅返回类型不同不足以成为函数的重载。
  • 不要将不同功能的函数定义为重载函数,以免出现对调用结果的误解。
//参数个数不同
void Add(int a, int b){
    a + b;
}

void Add(int a, int b, int c){ 
    a + b + c;
}
//参数类型不同
void Add(int a, int b){
    a + b;
}

void Add(int a, double b){  
    a + b;
}
//参数顺序不同
void Add(double b, int a){
    a + b;
}

void Add(int a, double b){
    a + b;
}
  • 函数重载的作用

      重载函数常用来实现功能类似而所处理的数据类型不同的问题,即功能相近的函数才会去重载,如同样是求和,在C语言中,不同类型的求和要使用不同的函数名,重载后你可以使用相同的函数名,在使用时可以减少记忆函数名的工作。要进行泛型就必须重载。

  • 为什么C++支持重载?C语言不支持

      首先需要清楚,函数重载是一个编译期行为,主要是通过命名倾轧(name mangling)来产生不同的汇编符号,让linker可以正确的link代码。
      C语言中,函数在编译后在库中的名字会确定下来,如果出现同名函数,就会在连接中报错。
      C++中,编译器会根据这些函数的不同参数列表,将同名的函数的名称做修饰,从而生成一些不同名称的预处理函数,来实现同名函数调用时的重载。
      

扩展:

缺省参数

  C++中,定义函数的时候可以让参数列表最右边连续若干个参数有缺省值,那么调用函数的时候,若相应位置不写参数,参数就是缺省值。
  参数缺省包括全缺省和半缺省。顾名思义,全缺省就是函数的所有参数都给出默认值,半缺省就是仅有函数的部分参数给出了默认值。

  • 注意
      1. 默认参数只可在函数声明中设定一次。只有在没有函数声明时,才可以在函数定义中设定。
      2. 如果一个参数设定了缺省值时,其右边的参数都要有缺省值
      3. 缺省参数调用时,则遵循参数调用顺序,自左到右逐个调用。
      4. 缺省值可以是全局变量、全局常量,甚至是一个函数。但不可以是局部变量。因为默认参数的调用是在编译时确定的,而局部变量位置与缺省值在编译时无法确定。
      5. 重载函数与默认参数共同使用时,避免出现二义性问题。
//e.g.
void fun(int x1,int x2 = 2,int x3 =3);
fun(1, 2, 3);//调用时有指定参数,则不使用缺省参数
fun(10, 8);//调用时指定两个参数,等同于 fun(10,8,3);
fun(10);//调用时指定一个参数,等同于 fun(10,2,3);
fun(10, , 8);//错误,只能最右边的连续若干个参数缺省
fun();//错误,x1没有缺省值
//e.g.
void add(int a = 1, int b = 2);
add();//正确,调用所有缺省参数,等同于 add(1, 2);
  • 函数参数可缺省值的目的在于提高程序的可扩充性

      即如果某个写好的函数要添加新的参数,而原先哪些调用该函数的语句,未必需要使用新增的参数,那么为了避免对原先哪些函数调用语句的修改,就可以使用缺省参数  

命名空间

  C++中命名空间的作用类似于操作系统中的目录和文件的关系,由于文件很多,不便管理,而且容易重名,于是人们设立若干子目录,把文件分别放到不同的子目录中,不同子目录中的文件可以同名。调用文件时应指出文件路径。

  命名空间的作用:建立一些互相分隔的作用域,把一些全局实体分隔开来。
  在C++语言中,命名空间是一种实体(entity),使用namespace来声明,并使用{ }来界定命名空间体(namespace body)。
例:

 namespace foo {
  int bar;
}

  可以根据需要设置多个命名空间,每个命名空间名代表一个不同的命名空间域,不同的命名空间不能同名。这样,可以把不同的库中的实体放到不同的命名空间中,或者说,用不同的命名空间把不同的实体隐蔽起来。过去我们用的全局变量可以理解为全局命名空间,独立于所有有的命名空间之外,它是不需要用 namespace声明的,实际上是由系统隐式声明的,存在于每个程序之中。
  可以多次声明和定义同一命名空间,每次给这一命名空间添加新成员。同名的命名空间即便声明位置不同,仍然是同一个实体。

引用命名空间的成员,有下述办法:

  • 使用命名空间的作用域解析运算符::,如:std::cout
  • using namespace 命名空间名[::命名空间名…];该语句使指定的命名空间中的目前已经声明的名字都提升到当前语句所在的作用域中可直接使用。如果引入的名字与该语句所在的声明区域的名字发生冲突,则编译器并不会发出任何警告信息,而只是用声明区域中的名字自动隐藏(hiding)命名空间中的同名成员,即使using namespace更靠后也是如此。
  • using 命名空间名::[命名空间名::……]成员名; 引入命名空间中的一个成员。如果引入的名称与局部名称发生同名冲突,编译器会报错。
      

可以在一个命名空间中引入其他命名空间的成员。 
例:

namespace myNameSpace{
       using namespace His_NameSpace;
       using OLib::List;
       void my_func(String &, List &);
}

命名空间可以有别名:namespace 别名 = 命名空间名; 这使得名字较长的命名空间可以方便地用较短的别名来引用。 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值