【 C++ 】 一文搞定——引用、内联、命名空间、缺省、重载

前言:这篇文章将带您了解C++基础中的知识点——命名空间、引用、内联、缺省、重载

😘我的主页:OMGmyhair-CSDN博客

一、命名空间namespace

1.可以嵌套定义,但是只能定义在全局

namespace ly
{int student = 1;int age = 21;void Print(void){printf("ly::Print");}namespace sister{int num = 2;void Print(void){printf("sister::Print");}}
}

2.多文件中定义的同名namespace会被认为是同一个

3.C++标准库都是放在一个叫做std(standard)的命名空间。例如endl、cin、cout都是里面的。

使用方式

当我们想使用命名空间中的变量或者函数的时候,有三种方式:

1.指定命名空间进行使用

在下面代码中,当我们想访问age时,就可以在前面加上ly::进行指定命名空间

namespace ly
{int student = 1;int age = 21;void Print(void){printf("ly::Print");}}}
int main()
{printf("ly的年龄:%d\n", ly::age);return 0;
}

2.将某一成员进行展开

namespace ly
{int student = 1;int age = 21;void Print(void){printf("ly::Print");}}using ly::age;int main()
{//1./*printf("ly的年龄:%d\n", ly::age);*///2.printf("ly的年龄:%d\n", age);printf("ly学生数量:%d\n", ly::student);return 0;
}

3.将该命名空间全部展开

namespace ly
{int student = 1;int age = 21;void Print(void){printf("ly::Print");}}//using ly::age;
using namespace ly;
int main()
{//1./*printf("ly的年龄:%d\n", ly::age);*///2./*printf("ly的年龄:%d\n", age);printf("ly学生数量:%d\n", ly::student);*///3printf("ly的年龄:%d\n", age);printf("ly学生数量:%d\n",student);return 0;
}


二、缺省

1.全缺省

void func(int a = 1, int b=2, int c = 3)
{printf("3\n");
}

2.半缺省

void func(int a, int b, int c = 3)
{printf("1\n");
}

关于缺省的小规则

1.不能跳跃给缺省值或者给实参

(1)跳跃给缺省值(X)

void func(int a=1, int b, int c = 3)
{printf("1\n");
}

只能从右往左给缺省值(√)

void func(int a, int b=2, int c = 3)
{printf("2\n");
}

(2)跳跃给实参(X)

void func(int a=1, int b, int c = 3)
{printf("1\n");
}
int main()
{func(, 2, );return 0;
}

2.当函数的定义与声明分离时,不能同时给定义和声明缺省值,只能在声明中给缺省值


三、引用

引用,用普遍的理解是起别名,其底层和指针相同。但是我们在理解时,引用不会再开辟空间,指针会再开辟空间。

引用的特性

1.引用在定义时必须初始化

2.一个变量可以有多个引用

3.引用一旦引用了一个实体,就不能在引用别的实体。

传引用返回

用下面的代码进行举例,在传值引用中,在最后的传值过程中,传值引用会将你想返回的值拷贝给一个临时对象,而原本的对象在出了函数之后就会被销毁。在下面的代码中,x出了函数就会被销毁,而x的值会赋给一个临时对象。

int fun(int x)
{x++;return x;
}

但是在传引用返回中,就省去了这一中间商过程。因为x出了函数并不会被销毁,x只是一个别名。

int& fun(int& x)
{x++;return x;
}

我们还可以通过传引用返回修改被引用的实体

struct Stack
{int arr[5];
};
Stack& funcReVerse(Stack &rarr)
{for (int i = 0; i < 5; i++){rarr.arr[i] = 5 - i;}return rarr;
}int main()
{Stack s;for (int i = 0; i < 5; i++){s.arr[i] = i + 1;}cout << funcReVerse(s).arr[0] << endl;funcReVerse(s).arr[0] = 999;for (int i = 0; i < 5; i++){cout << s.arr[i] << " ";}cout << endl;return 0;
}

权限放大

什么是权限放大呢?我们照例举一个例子:

int main()
{const int a = 30;int& ra = a;return 0;
}

本来a是不能被修改的,但是引用之后,我们却可以通过它的别名进行修改,此时就存在权限放大问题,上面的代码也会被编译器报错。

权限缩小

当理解了权限放大,那么理解权限缩小也就不是一个难事。

int main()
{int a = 30;const int& ra = a;return 0;
}

这段代码不会被编译器所报错,a本身还是可以修改的,但是当我们用别名取操作a时,却不能修改,此时就存在权限缩小的情况。

const引用

我们现在对const引用作进一步理解。

我们在这里引入一个知识点,临时对象具有常性

接下来我们来看看下面三种引用:

int main()
{int a = 1;int b = 2;double d = 2.5;//1.const int& ra = 30;//2.const int& rab = (a + b);//3.const int& rd = d;return 0;
}

以上三种引用都必须加上const,不然编译器会报错。

在第一种情况中,我们是对常量进行引用,因此加上const是不难理解的。

在第二种情况中,a+b得到的值会被赋给一个临时变量,而rab引用的就是这个临时变量。临时对象具有常性,所以要加const。你可能会觉得奇怪,临时变量不是临时的吗,使用完之后不就被销毁了吗,那么rab的引用不就成了一种类似“野指针”的情况吗?

值得注意的是,当临时变量被引用时,它不会立即被销毁,它的生命周期将跟着这个引用,当引用rab被销毁时,这个被引用的临时变量也会跟着被销毁。

在第三种情况中,会发生隐式转换,d会被转换为一个类型为int的临时对象,所以在这里rd并不是对d进行引用,而是对那个类型为int的临时对象进行引用。临时对象具有常性,所以这里也要加上const。

我们可以用地址的方式,来测试rd到底是不是对d进行引用:

可以看到d和rd的地址并不相同。


四、重载

当参数不同,函数名相同就构成了函数重载,需要注意的是,返回值类型的不同不能构成函数重载。因为在c\c++中,函数的返回值可以被忽略。

1.参数个数不同

void func(int a, int b)
{cout << a << b << endl;
}void func(int a)
{cout << a<< endl;
}

2.参数类型不同

void func(int a)
{cout << a<< endl;
}void func(double a)
{cout << a << endl;
}

3.参数顺序不同

void func(int a, int b, double c)
{cout << a << b << c << endl;
}void func(int a, double b, int c)
{cout << a << b << c << endl;
}

注意:当全局函数和类的成员函数同名时,并不算重载,因为它们作用域不同。

还有一种情况需要注意:

void Print(int a)
{cout << "Print int" << endl;
}void Print(int a = 10)
{cout << "Print float" << endl;
}int main()
{Print();return 0;
}

这两个函数存在重载,但是存在歧义,编译器会报错。


五、内联inline

好处:

1.内联可以替换宏代码,当我们在用宏代码写函数时,往往会发生一些意料不到的错误。相较于宏代码,内联函数更加安全,在调用时,编译器会对其进行检查。

2.内联函数代码直接替换函数调用,省去了函数调用的开销。

那是不是我们将每个函数都设置为内联更好呢?

并非如此

坏处:

1.内联是以代码膨胀为代价省去了函数调用的开销,当每一处内联函数都复制代码,那么总代码量会变得膨大,会消耗更多的内存空间。

2.当执行函数代码的时间对比函数调用的开销较大,使用内联的效率就不显得那么高了。

下面两种情况不适合使用内联:

1.函数内代码量大,使用内存代码消耗量很大

2.函数体内有循环,执行代码的时间比函数调用的开销大。

所以,有的编译器会根据函数定义体,自动取消内联。以及在vs的debug版本下默认不展开内联,方便调试。如果你想让内联在debug版本下展开需要设置以下两个地方。

1.右键你的项目,点击属性,来到下面这个页面,改为“程序数据库”

2.点击处于常规下面的优化,将内联函数扩展改为只适用于inline

注意,当使用内联时,不建议将声明和定义分开到两个文件中,会导致链接错误,因为inline被展开,就没有函数地址,链接时会出现报错。这时我们可以将内联函数的声明和定义都放在同一个头文件中。




如果这篇文章有帮助到你,请留下你珍贵的点赞收藏和评论,这对我会是极大的鼓励。学海无涯,我与你共勉!




本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/384177.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows wsl ubuntu系统安装桌面可视化

参考&#xff1a; https://www.bilibili.com/read/cv33557374/ 1&#xff09;首先先安装好wsl ubuntu系统 2&#xff09;安装 Ubuntu 桌面版 sudo apt purge -y acpid acpi-support modemmanagersudo apt-mark hold acpid acpi-support modemmanager sudo apt install ubunt…

数据库连接断开后,DBAPI的数据源如何自动重连

现象 在使用DBAPI的过程中&#xff0c;如果网络抖动导致数据库连接不上&#xff0c;发现DBAPI的数据源不能重连&#xff0c;必须重启DBAPI才能连上数据库 解决办法 在数据源的连接池参数配置druid.breakAfterAcquireFailurefalse注意在企业版的4.1.1及以上版本才可以配置连接…

捉虫笔记(1)之 WinDbg符号配置

WinDbg符号配置 1、WinDbg简单介绍 WinDbg 是微软的一款强大的调试工具&#xff0c;用于 Windows 平台的内核和用户模式调试。它提供了一系列强大的功能&#xff0c;包括内存和寄存器的查看、断点设置、堆栈跟踪、性能分析等。 WinDbg 的历史可以追溯到微软早期的调试工具&a…

OceanBase v4.2 特性解析:如何实现表级恢复

背景 在某些情况下&#xff0c;你可能会因为误操作而遇到表数据损坏或误删表的情况。为了能在事后将表数据恢复到某个特定时间点&#xff0c;在OceanBase尚未有表级恢复功能之前&#xff0c;你需要进行以下步骤&#xff1a; 利用OceanBase提供的物理恢复工具&#xff0c;您可…

ESP8266用AT指令实现连接MQTT

1准备工作 硬件&#xff08;ESP8266&#xff09;连接电脑 硬件已经烧入了MQTT透传固件 2实现连接 2-1&#xff08;进入AT模式&#xff09; 打开串口助手发送如下指令 AT 2-2&#xff08;复位&#xff09; ATRST 2-3&#xff08;开启DHCP&#xff0c;自动获取IP&#x…

Java二十三种设计模式-代理模式模式(8/23)

代理模式&#xff1a;为对象访问提供灵活的控制 引言 代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它为其他对象提供一个代替或占位符&#xff0c;以控制对它的访问。 基础知识&#xff0c;java设计模式总体来说设计模式分为三大类&#…

基于 HTML+ECharts 实现智慧运维数据可视化大屏(含源码)

智慧运维数据可视化大屏&#xff1a;基于 HTML 和 ECharts 的实现 在现代企业中&#xff0c;运维管理是确保系统稳定运行的关键环节。随着数据量的激增&#xff0c;如何高效地监控和分析运维数据成为了一个重要课题。本文将介绍如何利用 HTML 和 ECharts 实现一个智慧运维数据可…

14、如何⽤DDD设计微服务代码模型

在完成领域模型设计后&#xff0c;接下来我们就可以开始微服务的设计和 落地了。在微服务落地前&#xff0c;⾸先要确定微服务的代码结构&#xff0c;也就是我 下⾯要讲的微服务代码模型。 只有建⽴了标准的微服务代码模型和代码规范后&#xff0c;我们才可以将 领域对象映射到…

【Rust】所有权OwnerShip

什么是所有权 rust使用由编译器检查的一些规则构成的所有权系统来管理内存。且这不会影响程序的运行效率。 所有权规则 rust中每一个每一个值都有一个owner。在同一时刻&#xff0c;只能有一个owner。当这个owner超过范围&#xff0c;则该值会被丢弃。 String类型 为什么需…

全链路追踪 性能监控,GO 应用可观测全面升级

作者&#xff1a;古琦 01 介绍 随着 Kubernetes 和容器化技术的普及&#xff0c;Go 语言不仅在云原生基础组件领域广泛应用&#xff0c;也在各类业务场景中占据了重要地位。如今&#xff0c;越来越多的新兴业务选择 Golang 作为首选编程语言。得益于丰富的 RPC 框架&#xff…

虚拟机centos9搭建wordpress

目录 1. 更换yum源更新系统软件包&#xff1a; 1.1备份yum源 1.1.1创建备份目录&#xff1a; 1.1.2移动现有仓库配置文件到备份目录&#xff1a; 1.1.3验证备份&#xff1a; 1.2更换yum源 1.2.1添加yum源 1.2.2删除和建立yum缓存 1.3更新系统软件包 1.4 yum与dnf介绍…

单元测试的最佳实践

整体架构 合适的架构可以提升可测试性。比如菱形对称架构的模块化和解耦特性使得系统各个部分可以独立进行单元测试。这不仅提高了测试的效率&#xff0c;还能够减少测试的依赖性&#xff0c;提高测试准确性。 代码设计 代码设计和可测试性有密切关联。强烈建议一个方法的代码行…

Docker 安全及日志管理(包含SSL证书)

目录 一、Docker 存在的安全问题 二、Docker 架构缺陷与安全机制 三、Docker 安全基线标准 四、容器相关的常用安全配置方法 五、限制流量流向 六、镜像安全 七、DockerClient 端与 DockerDaemon 的通信安全 https的单向认证流程 https的双向认证流程 八、DockerClie…

Qt 使用视口和窗口作图

物理坐标系与逻辑坐标系 绘图设备的物理坐标系是基本的坐标系&#xff0c;通过 QPainter 的平移、旋转等坐标变换可以得到更容 易操作的逻辑坐标系。 物理坐标系也称为视口&#xff08;viewport&#xff09;坐标系&#xff0c;逻辑坐标系也称为窗口&#xff08; window&…

USB转多路串口-纯硬件实现串口数据传输指示灯电路

前言 串口相关产品往往要求有数据收发时LED闪烁&#xff0c;我们经常会用软件实现&#xff0c;在MCU内注册一个定时器&#xff0c;有数据发送时就闪烁一段时间。软件点灯这种方式存在两个缺陷&#xff0c;一是接收方向不好实现&#xff1b;二是定时器一般用固定频率&#xff0…

谷粒商城实战笔记-63-商品服务-API-品牌管理-OSS获取服务端签名

文章目录 一&#xff0c;创建第三方服务模块thrid-party1&#xff0c;创建一个名为gulimall-third-party的模块2&#xff0c;nacos上创建third-party命名空间&#xff0c;用来管理这个服务的所有配置3&#xff0c;配置pom文件4&#xff0c;配置文件5&#xff0c;单元测试6&…

Selenium 的使用

selenium 是一个自动化测试工具&#xff0c;利用它可以驱动浏览器完成特定的操作&#xff0c;例如点击&#xff0c;下拉等&#xff0c;还可以获取浏览器当前呈现的页面的源代码&#xff0c;做到所见即所爬&#xff0c;对于一些 JavaScript 动态渲染的界面来说&#xff0c;这种爬…

封装和桥接Unity 协程体系

简介 协程&#xff08;Coroutine&#xff09;在C#中是一种特殊的函数&#xff0c;它允许开发者编写可以暂停执行并在未来某个时刻恢复执行的代码块。协程通常用于实现异步操作&#xff0c;如延时执行、等待某个事件发生、或者分段执行复杂的任务。在Unity游戏引擎中&#xff0c…

算法之递归算法

递归是非常常见的一种算法&#xff0c; 也比较难以理解&#xff0c;简而言之&#xff0c;递归就是写了一个方法&#xff0c;方法中还调用了该方法&#xff0c;相当于自己调用自己&#xff0c;如果书写不当&#xff0c;就会有堆栈溢出的风险&#xff0c;无法跳出。 所以我们编写…

内网对抗-隧道技术篇防火墙组策略HTTP反向SSH转发出网穿透CrossC2解决方案

知识点&#xff1a; 1、C2/C2上线-CrossC2插件-多系统平台支持 2、隧道技术篇-应用层-SSH协议-判断&封装&建立&穿透 3、隧道技术篇-应用层-HTTP协议-判断&封装&建立&穿透隧道技术主要解决网络通讯问题&#xff1a;遇到防火墙就用隧道技术&#xff0c;…