【C++】命名空间、缺省参数、函数重载、引用

2024-05-13 19:12

本文主要是介绍【C++】命名空间、缺省参数、函数重载、引用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1.认识命名空间
  • 2.命名空间的使用
  • 3.C++的输入和输出
  • 4.缺省参数
    • 4.1缺省参数的概念
    • 4.2缺省参数的分类
  • 5.函数重载
  • 6.引用
    • 6.1引用的概念
    • 6.2引用的特性
    • 6.3常引用(重点题目)
    • 6.4引用和指针的区别

1.认识命名空间

C++总计63个关键字,C语言32个关键字在这里插入图片描述

下面让我们学习一下第一个关键字namespace

首先,我们来看下面的代码
在这里插入图片描述
我们定义了一个名为 rand 的全局变量,此时可以正确的打印出来。

当我们引用了<stdlib.h>这个头文件时,我们发现此时代码就会报错,如下图。
在这里插入图片描述
在这里插入图片描述
我们都知道,rand是一个产生随机数的函数名,此时该名称与我们定义的全局变量命名发生了冲突,编译器就不知道选哪个了。
然而,C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决

使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。

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

命名空间有几种使用方式:

  1. 正常的命名空间定义
//aim 是命名空间的名字,实际中一般以项目名称命名
namespace aim1
{int rand = 10;
}
  1. 嵌套定义
namespace aim1 //命名空间1
{int rand = 10;namespace aim2//命名空间2{int rand = 20;}
}
  1. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中

两个文件中的同名命名空间最后会进行合并,因此会出现重定义问题。
在这里插入图片描述

注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中

2.命名空间的使用

使用命名空间解决访问冲突的问题后,我们发现仍然访问不到它,此时rand使用的依然是rand函数,打印出来函数的地址。
在这里插入图片描述

下面就来介绍一下命名空间是如何访问的,有3种方式:

  1. 命名空间名称作用域限定符

作用域限制符就是两个冒号,此时我们就可以访问到定义的变量了
在这里插入图片描述

  1. 使用using将命名空间中某个成员引入

using是我们学习的第二个关键字
在这里插入图片描述

我们发现,只有被引入的成员才可以被访问,其它成员依旧不可以。若想访问其它成员,也需要将其引入

  1. 使用using namespace 命名空间名称引入

在这里插入图片描述
此时我们发现,a变量可以访问了,然而rand又出现了问题。什么原因呢?

我们知道,编译器的默认查找是:
a. 当前局部域
b. 全局域
b. 到展开的命名空间中查找

此时我们的全局域中和命名空间中都有rand,显然不知道选哪一个,此时我们就需要指定了。因此使用第三种方式时要慎重,不然就是自找麻烦
/
此时我们就可以发现,若某一成员需要经常使用,可以将其引入;对于不常使用的成员,可以使用命名空间加作用域限定符
在这里插入图片描述
很显然,引入了成员后使用更加方便。

自己在学习中遇到的问题:为什么使用命名空间中的宏时不需要指定?
在这里插入图片描述
宏定义是在编译时预处理阶段完成的,而命名空间是在编译时进行名称空间分配和解析的在预处理阶段,编译器并不知道命名空间的存在,所以它无法对命名空间进行解析,因此也就无法指定命名空间。
当使用命名空间内的宏时,编译器会在预处理阶段将宏展开成相应的代码,而展开后的代码中不包含命名空间,因此不需要指定命名空间

3.C++的输入和输出

  • 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件以及按命名空间使用方法使用std

在这里插入图片描述

  • cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中。
  • <<流插入运算符,>>流提取运算符。
  • 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。C++的输入输出可以自动识别变量类型
    浮点数输出时,也不会像scanf 那样默认小数点后6位;它是原样输出。

在这里插入图片描述

  • 输入时,也不需要取地址了

在这里插入图片描述

std命名空间的使用惯例:
std是C++标准库的命名空间,如何展开std使用更合理呢?

  1. 日常练习中,建议直接using namespace std即可,这样就很方便
  2. using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模大,就很容易出现。所以在项目开发中建议使用像 std::cout这样使用时指定命名空间 或 using std::cout展开常用的库对象/类型等方式

4.缺省参数

4.1缺省参数的概念

缺省参数是声明定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
在这里插入图片描述

4.2缺省参数的分类

  1. 全缺省参数

在这里插入图片描述
2. 半缺省参数

在这里插入图片描述

注意:

  • 半缺省参数必须从右往左依次来给出,不能间隔着给。

在这里插入图片描述

  • 缺省参数不能在函数声明和定义中同时出现

如果声明与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值
在这里插入图片描述

在这里插入图片描述

  • 缺省值必须是常量或者全局变量

5.函数重载

C语言是不支持同名函数存在的,C++支持。

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

  1. 参数类型不同

在这里插入图片描述

  1. 参数类型的顺序不同

在这里插入图片描述

  1. 参数的个数不同

在这里插入图片描述

注意:

  • 同一作用域中,同名函数要想同时存在,必须满足重载的规则。
  • 不同作用域,可以有同名函数
  • 返回值是不构成重载的(返回值不像参数,编译器对它是无法区分的,它也不是必须的)
  • 重载的规则是针对于参数的类型和个数,与参数的名称无关、参数缺省无关

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

  • 因为在程序进行链接的时候,是使用函数名去找地址的,如果声明和定义分离,C语言是直接使用函数名去找,区分不开。
  • C++使用函数名修饰规则,可以区分。

6.引用

6.1引用的概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间,它们的地址是一样的

定义方式:类型& 引用变量名(对象名) = 引用实体;

在这里插入图片描述

注意:引用类型必须和引用实体是同种类型的

在这里插入图片描述
引用就是祖师爷本贾尼觉得C语言指针不好才搞得,下面的代码就比指针方便的多。

在这里插入图片描述

6.2引用的特性

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个实体,再不能引用其他实体
  1. 引用在定义时必须初始化

在这里插入图片描述

  1. 一个变量可以有多个引用
int main()
{int x = 10;//一个变量多个引用int& a = x;int& b = x;int& c = x;int& d = x;return 0;
}
  1. 引用一旦引用一个实体,再不能引用其他实体

下面的代码中是将a变成y的别名?还是将y赋值给a呢?
在这里插入图片描述
很显然,它是将y赋值给了a

6.3常引用(重点题目)

void TestConstRef()
{const int a = 10;//int& ra = a;   // 该语句编译时会出错,a为常量const int& ra = a;// int& b = 10;  // 该语句编译时会出错,b为常量const int& b = 10;double d = 12.34;//int& rd = d;  // 该语句编译时会出错,类型不同,d为常量const int& rd = d;
}
  1. 权限的平移
int main()
{const int m = 0;//权限的放大//int& n = m; //error  m的权限是可读,n的权限是可读可写的//权限的平移const int& n = m;//可以//可以,不是权限的放大//只是将m的值拷贝给x,x的修改不影响pint x = m;return 0;
}
  1. 权限的缩小

在这里插入图片描述

  1. 权限的放大(错误、易错
int main()
{const int m = 0;//cosnt修饰指针,左定值,右定向//p1可以修改,*p1不可以,const修饰的是*p1const int* p1 = &m;p1++;//权限的放大,不可以//int* p2 = p1;  //易错//权限平移,可以const int* p2 = p1;return 0;
}

总结:值之间没有权限的放大和缩小的概念,只是一个拷贝;指针与引用有权限放大与缩小的概念,权限只可以缩小,不可以放大

6.4引用和指针的区别

在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。
在这里插入图片描述

在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

int main()
{int x = 0;int& y = x;y = 10;int n = 10;int* p = &n;*p = 20;return 0;
}

我们来看引用和指针的反汇编对比
在这里插入图片描述

引用和指针的不同

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
  2. 引用在定义时必须初始化,指针没有要求
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
  4. 没有NULL引用,但有NULL指针
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  7. 有多级指针,但是没有多级引用
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  9. 引用比指针使用起来相对更安全

这篇关于【C++】命名空间、缺省参数、函数重载、引用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/986577

相关文章

MySQL中时区参数time_zone解读

《MySQL中时区参数time_zone解读》MySQL时区参数time_zone用于控制系统函数和字段的DEFAULTCURRENT_TIMESTAMP属性,修改时区可能会影响timestamp类型... 目录前言1.时区参数影响2.如何设置3.字段类型选择总结前言mysql 时区参数 time_zon

Python如何使用seleniumwire接管Chrome查看控制台中参数

《Python如何使用seleniumwire接管Chrome查看控制台中参数》文章介绍了如何使用Python的seleniumwire库来接管Chrome浏览器,并通过控制台查看接口参数,本文给大家... 1、cmd打开控制台,启动谷歌并制定端口号,找不到文件的加环境变量chrome.exe --rem

C++中实现调试日志输出

《C++中实现调试日志输出》在C++编程中,调试日志对于定位问题和优化代码至关重要,本文将介绍几种常用的调试日志输出方法,并教你如何在日志中添加时间戳,希望对大家有所帮助... 目录1. 使用 #ifdef _DEBUG 宏2. 加入时间戳:精确到毫秒3.Windows 和 MFC 中的调试日志方法MFC

Linux中Curl参数详解实践应用

《Linux中Curl参数详解实践应用》在现代网络开发和运维工作中,curl命令是一个不可或缺的工具,它是一个利用URL语法在命令行下工作的文件传输工具,支持多种协议,如HTTP、HTTPS、FTP等... 目录引言一、基础请求参数1. -X 或 --request2. -d 或 --data3. -H 或

Oracle的to_date()函数详解

《Oracle的to_date()函数详解》Oracle的to_date()函数用于日期格式转换,需要注意Oracle中不区分大小写的MM和mm格式代码,应使用mi代替分钟,此外,Oracle还支持毫... 目录oracle的to_date()函数一.在使用Oracle的to_date函数来做日期转换二.日

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

详解Spring Boot接收参数的19种方式

《详解SpringBoot接收参数的19种方式》SpringBoot提供了多种注解来接收不同类型的参数,本文给大家介绍SpringBoot接收参数的19种方式,感兴趣的朋友跟随小编一起看看吧... 目录SpringBoot接受参数相关@PathVariable注解@RequestHeader注解@Reque

Java向kettle8.0传递参数的方式总结

《Java向kettle8.0传递参数的方式总结》介绍了如何在Kettle中传递参数到转换和作业中,包括设置全局properties、使用TransMeta和JobMeta的parameterValu... 目录1.传递参数到转换中2.传递参数到作业中总结1.传递参数到转换中1.1. 通过设置Trans的

java如何调用kettle设置变量和参数

《java如何调用kettle设置变量和参数》文章简要介绍了如何在Java中调用Kettle,并重点讨论了变量和参数的区别,以及在Java代码中如何正确设置和使用这些变量,避免覆盖Kettle中已设置... 目录Java调用kettle设置变量和参数java代码中变量会覆盖kettle里面设置的变量总结ja