C++:函数重载、缺省参数及命名空间的理解

类型

在 C 语言中,类型有内置类型与自定义类型之分。其中内置类型就是常常用到的 int、char等。而自定义类型就是定义的一些数据结构struct/enum/union等,如 typedef struct LinkNode

而在 C++ 当中,类型也分为内置类型与自定义类型。内置类型与 C 语言一致。而自定义类型分为:struct/class/enum/union,我们发现,相比于 C ,C++ 多了一个 class,而这个就是 类!!!


命名空间

在解释命名空间之前,首先先看一段代码。

#include <iostream>

using namespace std;

namespace test {
    a = 10;
};

int main()
{
    cout<<a<<endl;

    return 0;
}

这段代码在编译的时候能否编译通过呢?答案肯定是不行的,因为在 main 函数里,用了 test 域里的 a ,而并没有展开命名空间test ,所以在使用其内部元素时,编译器无法找到,自然而然的就编译不通过。其实我们常常用的 cout<<a<endl 这也是命名空间的元素。只不过在使用之前用using namespace std 展开了 std 这个 C++ 标准库的一个命名空间。

为什么要存在命名空间?

命名空间的存在时为了防止命名冲突的!!!
再看下面一段代码。

#include <iostream>

using namespace std;

namespace test1 {
  int a = 10;
};

namespace test2 {
  int a = 20;
};

using namespace test1;

int main()
{
  cout<<a<<endl;

  return 0;
}

main 函数调用 cout<<a<<endl 打印 a 的时候,在上面的了两个命名空间内都定义了a, 而我们仅仅只展开了 test1 所以在访问时,只能够访问展开的命名空间。倘若这个时候,我们同时展开两个命名空间test1 和 test2并且在main 函数内部,定义一个变量a,那么这个时候,编译器会采用就近原则,选择最近的 a去访问,也就是访问main内定义的。

当我们展开了命名空间std 后,那么在后面的变量命名当中一定要注意避免与 std 内的元素重名。


函数重载

在 C 语言中,不允许两个函数同样的命名。

#include <stdio.h>

void Test(int a)
{
  printf("%d\n",a);
}

void Test(char a)
{
  printf("%c\n",a);
}

int main()
{
  Test('a');
  Test(1);
}

这里写图片描述

但是在 C++ 里是支持的。

#include <iostream>

void Test(int a)
{
  cout<<a<<endl;
}

void Test(char a)
{
  cout<<a<<endl;
}

int main()
{
  Test('a');
  Test(1);
}

这里写图片描述

把这种函数名相同,其参数的类型不同的方式,叫作函数的重载。以下几种方式都是函数的重载。

#include <iostream>

using namespace std;

void Test(int a)
{
  cout<<a<<endl;
}

void Test(char a)
{
  cout<<a<<endl;
}

vod Test(int a, char b)
{
  cout<<a<<endl;
  cout<<b<<endl;
}

vod Test(char b, int a)
{
  cout<<a<<endl;
  cout<<b<<endl;
}
C++ 如何支持重载?

在探讨这个问题时,我们先利用 Linux 上的小工具objdump-D 选项来查看一下可执行文件test的汇编。

#include <iostream>

void Test(int a)
{
  cout<<a<<endl;
}

void Test(char a)
{
  cout<<a<<endl;
}

int main()
{
  Test('a');
  Test(1);
}

这是test.cpp里的代码。再来看看它的汇编。
这里写图片描述

可以看到,在main 函数的上面,就是我们重载的两个函数Test。这两个函数的参数不同,所以在汇编里,其实看到的两个函数名分别为_Z4Testi_Z4Testc我们发现,它俩的区别就是参数不同,而编译器在编译时,将它们的函数名解析成了本身的函数名加上参数类型的首字母。这样,就能够保证函数的重载。

(注:在使用 objdump 时,可能会涌出大量的数据,导致我们无法看到想要的数据。我们可以将这些数据导入文件, 然后用 vim 在文件中查找关键字即可查找到。)


缺省参数

在 C++ 的函数中,是可以有默认参数的。

如下:

#include <iostream>

using namespace std;

void Test(int a = 1, int b = 2)
{
  cout<<a<<b<<endl;
}

int main()
{ 
  Test();
}

也可以半缺省,也就是说有的参数缺省有的参数不缺省。但是半缺省只能够从右往左半缺省!!!

#include <iostream>

using namespace std;

void Test(int a, int b = 2)
{
  cout<<a<<b<<endl;
}

int main()
{ 
  Test(1);
}

欢迎大家共同讨论,如有错误及时联系作者指出,并改正。谢谢大家!

猜你喜欢

转载自blog.csdn.net/liuchenxia8/article/details/80975671