现在的位置: 首页 > 算法 > 正文

为什么会存在函数重载?和引用有什么区别

2020年01月15日 算法 ⁄ 共 1791字 ⁄ 字号 评论关闭

  为什么会存在函数重载?有时候需要根据不同的数据类型调用不同名的函数,如果这种情况比较多的话,对于写程序的人来说,要分别编写功能相同而名字不同的函数,是很不方便的。所以在c++中引入了函数重载。

  那什么又是函数重载呢?

  函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数、类型、顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。函数的重载即对一个函数名重新赋予它新的含义,使一个函数名可以多用。**所谓重载,其实就是“一物多用”。

  以下是关于函数重载的例子:

  void Test()

  {}

  void Test(int a)

  {}

  //这两个函数形成重载,因为形参的个数不同

  int Add(int left,char right)

  {}

  int Add(int left, int right)

  {}

  //此两个函数形成重载,因为形参类型不同

  void Test(int a,char b)

  {}

  void Test(char a,int b)

  {}

  //此两个函数形成重载,因为形参类型的次序不同

  void Test()

  {}

  int Test()

  {}

  //这两个函数并不能形成重载,因为函数重载是与返回值类型无关的。

  int Add(int left, int right)

  {

  return left+right;

  }

  double Add(double left, double right)

  {

  return left+right;

  }

  long Add(long left, long rigjt)

  {

  return left+right;

  }

  int main()

  { //系统会根据参数的不同而找到对应的函数并调用。

  Add(10, 20);

  Add(10.0, 20.0);

  Add(10L, 20L);

  return 0;

  }

  20

  c语言中不支持函数重载,在c++中却可以支持函数重载,这是为什么呢?

  翻译过程一般分为: 预处理—-编译——汇编——链接

  预处理:展开头文件,宏替换,去掉注释,条件编译等工作。生成.i文件

  编译:语法检查,生成汇编代码。 生成.s文件

  汇编:将汇编代码转成机器码 。 生成.o文件

  链接:将之前生成的文件链接到一起,生成可执行文件。 生成.out文件

  如果有多个.c文件,注意 在链接之前各文件都是独立向下进行的,各文件之间没有交集。

  所以支持重载问题就出在链接这个阶段上,c语言在链接的时候根据函数名找要调用的函数,而c++而是根据函数名和参数类型来寻找要调用的函数(函数名修饰规则)

  在c语言和c++中对函数名字的处理规则不一样。编译器在对函数编译完成后,实际上已经对函数的名字进行修改了。如下这两个函数形成重载了

  int Add(int left,char right)

  int Add(int left, int right)

  在c语言中,编译器把这两个函数的名字都修改成了_Add,这两个函数无法区分,所以c语言中无法支持函数重载。但在c++中两者的函数名分别被修改成了

  (?Add@@YAHHD@z)

  (?Add@@YAHHH@z)

  所以c++可以进行函数重载。

  C++中能否将一个函数按照C的风格来编译?

  C++中可以通过在函数声明前加 extern “C” 将一个函数按照 C 语言的风格来进行编译。函数在C中和C++中编译过的函数名字是不一样的。加上extern”C”是说明是说明C已经编译过的。 C++想要调用已经编译过的C函数,由于编译过的名字不同,是不能直接调用的,所以C++加extern“C”声明来解决这个问题。

  例如:假设某个函数的原型为:int add(int left, int right);该函数被C 编译器编译后在库中的名字为_add, 而C++ 编译器则会产生像_add_int_int 之类的名字,加上extren”C”后,就相当于告诉编译器,函数add是个C编译后的函数,在库里应该找的是_add,而不是_add_int_int.

  需要注意的是:不同的编译器有不同的重命名方式,这里仅仅举例说明,实际情况可能并非如此。

  下面两个函数能形成函数重载吗?

  void FunTest(int a = 10)

  {

  cout<<"void FunTest(int)"<   }   void FunTest(int a)   {   cout<<"void FunTest(int)"<   }   第一个函数在调用时,可以传参,也可以不传参,不传参就用给出的这个缺省值。第二个函数在调用时一定要传参。所以,当传参时,这两个函数无法确认调用哪一个。

抱歉!评论已关闭.