【C++入门第一期】命名空间 缺省参数 函数重载 的使用方法及注意事项
创始人
2024-05-23 15:47:10
0

目录

  • 简介
  • 命名空间
    • 为何会有命名空间
    • 命名空间的定义
    • 嵌套定义
    • 命名空间的使用
      • 作用域限定符
      • using 将命名空间中某个成员引入
      • using namespace 将该空间所有成员引入
  • 缺省参数
      • 全缺省参数函数
      • 半缺省参数函数
      • 如何给缺省值
  • 函数重载
    • 函数重载的概念
    • 函数重载的三种类型
      • 1:函数参数类型不同
      • 2:参数个数不同
      • 3:参数类型顺序不同
    • 分析与总结
      • linux下函数修饰规则
      • Windows下修饰规则
      • 总结

简介

经过许久的C语言学习,前不久终于开始了c++的学习经过总结写下了这篇文章.
总结:C++总计63个关键字,C语言32个关键字
在这里插入图片描述
废话少说直接开始第一个知识点

命名空间

首先按照学习一门语言的惯例写一段 Hello world 入门代码.
在这里插入图片描述
刚开始学能你不清楚为什么我只打印一句 Hello world 包含头文件我理解但为啥还要带一句 using namespace std 。有人可能表示这是命名空间书上说过,对大致上可以这么理解。

但是你知道他为啥要这么定义吗?定义规则是什么吗?自己该如何定义吗?

如果都知道,很高兴的和你说您可以跳过本篇这个知识点了

为何会有命名空间

一个组,一起开发一个大型项目。但是他们但他们编写程序时就可能出现重名的函数,变量,结构体等,合并时就出现问题了大量的命名冲突。最初,人们就想了个办法,将名字取得更长更复杂来避免重复,可这样做却给编写和阅读带来了困难。后来,人们创造了命名空间这个概念,它能有效地指出某个标示符到底属于哪个库。

命名空间的定义

定义命名空间,需要使用到namespace 关键字,后面跟命名空间的名字,然后接一对{ }即可,{ }中即为命名空间的成员

如下 zgb 是命名空间的名字,大括号中的 sum 变量和 Add 函数及结构体 book 是 zgb 空间的成员

namespace zgb
{int sum = 10;int Add(int x, int y){return x + y;}struct book{char name[15];}mm;
}

嵌套定义

可如下嵌套定义命名空间

namespace binbang
{int a = 29;namespace binbin{int Add(int x, int y){return x + y;}}
}

命名空间相同时如相互的成员名均不同则会合并相同的命名空间,但成员名相同时则会发生命名冲突从而报错。
在这里插入图片描述
在这里插入图片描述
总结:
1:命名空间中可以定义变量,函数,结构体等非常自由。
2:命名空间可以嵌套定义
3:注意若同一工程中,命名空间名字如果相同,相同空间名中的成员会合并为一个命名空间,但这就丧失了命名空间的作用,因为由于是合并而成的里面的命名可能冲突导致报错
4:只要命名空间名字不同,每个命名空间是互不干扰的就像局部变量一样

命名空间的使用

命名空间的使用有三种方式

作用域限定符

使用方法命名空间名 : : 该空间成员(变量函数结构体等),符号左边写命名空间名,右边写该该空间成员
举例如下:
在这里插入图片描述
嵌套时也是如图加作用域限定符即可
在这里插入图片描述

学会了使用现在咱验证一下不同命名空间同名变量是否会冲突,答案是不会。如图
在这里插入图片描述

using 将命名空间中某个成员引入

使用方法:using 命名空间名 : : 该空间成员

如下图, using bb::sum;等于是声明了 bb 中的变量 sum,后面可以不加作用域限定符即可直接使用。注意如果该语句在全局中则该声明全局有效,如该语句在局部则该声明局部有效
在这里插入图片描述

using namespace 将该空间所有成员引入

使用方法:using namespace 命名空间名称
作用:将该空间所有成员引入,如下面using namespace std,就是将命名空间 std 中的内容全部展开(声明/引入),其中就包括了cout 。所以可以之后cout可以直接使用;
在这里插入图片描述
注意:该命令如在全局中使用,那将使命名空间失去意义,如果全局中与 引入(声明/展开)成员同名的变量或函数等将发生冲突,不同命名空间均在全局或同一个局部空间使用using namespace 将该空间所有成员引入(声明/展开)时也可能发生冲突
在这里插入图片描述
using namespace,一般在刷题,测试及局部中使用比较合适,工程和全局中可控性太低

缺省参数

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参

如下图,test7 函数中有一个缺省值 x = 10,当调用 test7 函数时传参为22则,x 等于22当调用 test7 函数时参数为空则 x 默认等于缺省值10
在这里插入图片描述

全缺省参数函数

概念:指函数的参数均为均有缺省值
如下

void test9(int x = 10, int  y = 20, int  z = 30)
{cout << x << endl;cout << y << endl;cout << z << endl;}

半缺省参数函数

概念:指函数的部分参数有缺省值,注意参数必须从右往左连续缺省,简要记无缺省值参数不能在缺省值参数的右边
如下是半缺省参数函数

void test9(int x , int  y = 20, int  z = 30)
{cout << x << endl;cout << y << endl;cout << z << endl;}

为啥说无缺省值参数不能在缺省值参数的右边呢?

如下无缺省值参数出现在缺省值参数的右边,程序直接报错了。因为函数传参时是从左到右一 一对应的不能跳过中间参数进行传参,所以没有缺省值的参数需要在右边并且连续,达到优先及易区分等目的。
在这里插入图片描述

如何给缺省值

在实际使用中.c文件中的函数须在.h中声明时,如果要声明的函数带缺省值,应在.h文件中给缺省值,定义函数时不用给缺省值,如果两个都给缺省值那编译器将会报错,因为不知道该用那个

如下编译器将会报错

//a.h     (.h文件)
void zgb(int a = 10);
// a.cpp (.cpp文件)
void zgb(int a = 20)
{}

因为声明都没有缺省值那,函数的缺省值又从何而来呢
正确方式

//a.h     (.h文件)
void zgb(int a = 10);
// a.cpp (.cpp文件)
void zgb(int a )
{}

总结:

  1. 半缺省参数必须从右往左依次来给出,不能间隔着给
  2. 缺省参数不能在函数声明和定义中同时出现
  3. 缺省值必须是常量或者全局变量
  4. C语言不支持(编译器不支持)

函数重载

函数重载的概念

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

函数重载的三种类型

1:函数参数类型不同

如下函数同名,但函数参数类型不同,如下当函数调用时传参为int 类型则会调用函数参数为int类型的Add函数,反之则调用参数为double类型的Add函数;

//函数重载
int Add(int x, int y)
{cout << "Add(int x, int y)" << endl;return x + y;
}
double Add(double x, double y)
{cout << "Add(double x, double y)" << endl;return x + y;
}
void tese2()//函数重载,函数参数类型不同
{Add(1, 2);//编译时就链接好了对应函数Add(1.3, 1.5);
}

2:参数个数不同

如下函数同名,但函数参数个数不同,如下当函数调用时只传一个参数则使用一个参数Add函数,当函数调用时传两个参数则使用两个参数Add函数。(当然传参与函数参数需相同)

int Add( int y, char x)
{cout << "Add( int y, char x)" << endl;return y;
}
int Add(int x)
{cout << "Add(int x)" << endl;return x;
}
void tese4()//函数重载,函数参数个数不同
{Add(1);Add(2, 4);
}

3:参数类型顺序不同

如下函数同名,但函数各参数类型顺序不同,如下当调用函数传参时参数1为 char 类型参数二为 int 类型,则会调用 int Add(char x, int y)

当调用函数传参时参数1为 int 类型参数二为 char 类型,则会调用 int Add( int y, char x)

int Add(char x, int y)
{cout << "Add(char x, int y)" << endl;return x;
}
int Add( int y, char x)
{cout << "Add( int y, char x)" << endl;return y;
}
void tese3()//函数重载,函数参数顺序不同
{Add('a', 1);Add(1, 'a');
}

分析与总结

1:为什么C++支持函数重载,而C语言不支持函数重载呢?
在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接
在这里插入图片描述

  1. 实际项目通常是由多个头文件和多个源文件构成,而通过C语言阶段学习的编译链接,我们可以知道,【当前a.cpp中调用了b.cpp中定义的Add函数时】,编译后链接前,a.o的目标文件中没有Add的函数地址,因为Add是在b.cpp中定义的,所以Add的地址在b.o中。
  2. 所以链接阶段就是专门处理这种问题,链接器看到a.o调用Add,但是没有Add的地址,就会到b.o的符号表中找Add的地址,然后链接到一起
  3. 链接时,面对Add函数,链接接器会使用哪个名字去找呢?这里每个编译器都有自己的函数名修饰规则
  4. 由于Windows下vs的修饰规则过于复杂,而Linux下g++的修饰规则简单易懂,下面我会使用g++演示函数修饰后的名字。
  5. 通过下面我们可以看出gcc的函数修饰后名字不变。而g++的函数修饰后变成【_Z+函数长度+函数名+类型首字母】。

linux下函数修饰规则

首先看看采用C语言编译器编译后结果,如下图在linux下,采用gcc编译完成后,函数名字的修饰没有发生改变。
在这里插入图片描述
在看看采用c++编译器编译后的结果,如下图在linux下,采用g++编译完成后,除main函数外的函数名字的修饰发生改变,编译器将函数参数类型信息添加到修改后的名字中。
在这里插入图片描述

Windows下修饰规则

由于Windows下Vs编译时函数的修饰规则较为复杂还是直接看下图吧
在这里插入图片描述
对比Linux会发现,windows下vs编译器对函数名字修饰规则相对复杂难懂,但道理都是类似的,我们就不做细致的研究了。

总结

  1. 通过上述举例应该理解了C语言没办法支持重载,是因为同名函数没办法区分。而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。
  2. 注意:如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办法区分
  3. 重载函数在运行时被调用怎么找到对应函数?在程序链接时,每条函数调用指令就已经链接好了对应函数地址,所以运行时使用重载函数效率也不会降低。

C++入门第一期内容就这些了,下期会更新引用/内联函数/auot等

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...