C++ 命名空间|缺省参数|函数重载

一、命名空间

1.什么是命名空间

命名空间(namespace)是C++中的一种机制,用来解决不同代码库之间的命名冲突问题

先来看一个例子:

#include <iostream>

void print() 
{
    std::cout << "Hello from print()" << std::endl;
}

// 假设这里有另一个库也定义了print函数
void print() 
{
    std::cout << "Hello from another print()" << std::endl;
}

int main() 
{
    print();  // 编译错误,函数名冲突
    return 0;
}

这是在写大型项目时经常容易遇到的事情,假如这两个库分别由两个不同的人编写,可能这两个库的代码分别能在各自的环境中正常运行,但当代码提交到一起时,就会出现命名冲突问题问题。

为了解决这种问题,C++提出了命名空间的概念,就是通过把全局范围内的变量、函数和类等放在一个逻辑命名空间内,避免名字重叠。 就像这样:

#include <iostream>

namespace FirstLibrary 
{
    void print() 
    {
        std::cout << "Hello from FirstLibrary::print()" << std::endl;
    }
}

namespace SecondLibrary 
{
    void print() 
    {
        std::cout << "Hello from SecondLibrary::print()" << std::endl;
    }
}

int main() 
{
    FirstLibrary::print();  // 正常调用
    SecondLibrary::print(); // 正常调用
    return 0;
}

命名空间包含的成员可以是变量、函数、类和结构体、枚举、类型定义....你还可以套娃在命名空间空间中嵌套命名空间(很少这样做),例如:

namespace MyLibrary
{
	int a = 10;
	double b = 1.2;

	int Add(int left, int right)
	{
		return left + right;
	}

	class MyClass 
    {
        public:
        void display() 
        {
            // 方法实现
        }
    };

    struct Poiont
    {
	    int x;
	    int y;
    };

    enum MyEnum 
    {
        VALUE1,
        VALUE2
    };

    typedef int MyInt;

	namespace MyLibrary_2
	{
		int a = 0;
	}

	//... ...
}

2.如何访问命名空间的成员

2.1作用域展开符

即 直接在要访问的成员名称前加`::`。

`::`是作用域限定符,不作用域限定符则无法访问到该命名空间的成员,因为编译器默认只在全局范围中查找。

int main() 
{
	// 访问变量
	std::cout << MyLibrary::a << std::endl;

	// 调用函数
	MyLibrary::Add(1,2);

	// 使用类
	MyLibrary::MyClass obj;
	obj.display();

	// 使用结构体
	MyLibrary::Poiont  s = { 1, 9 };
	std::cout << "Point: x = " << s.x << ", y = " << s.y << std::endl;

	// 使用枚举
	MyLibrary::MyEnum e = MyLibrary::VALUE1;
	std::cout << "MyEnum value: " << e << std::endl;

	// 使用类型别名
	MyLibrary::MyInt i = 100;
	std::cout << "MyInt: " << i << std::endl;

	// 调用嵌套命名空间的函数
	std::cout << MyLibrary::MyLibrary_2::a << std::endl;

	return 0;
}

 

2.2命名空间展开

即 使用`using namespace`指令,命名空间展开可以分为全展开和半展开。

全展开:使用using namespace

using namespace MyLibrary;

使用这条语句之后,MyLibrary中的所有成员均可直接访问,即不用在成员前加`::`

#include<iostream>
using namespace std;

int main()
{
	cout << "using namespace std" << endl;
	return 0;
}

如上面这段代码,使用 using namespace std 将C++标准命名空间展开后,就可以直接访问std里面的cout和endl了

半展开:使用using

using MyLibrary::a;

使用`using`引入特定的成员,这样在程序中即可直接访问该成员

2.3总结

这三种方式各有优劣,直接使用作用域限定符最为清晰明确,但较为冗长;

`using` 声明适合局部引入特定成员;

`using namespace` 指令则最简便,但可能引入命名冲突风险

3.注意事项

  1. 命名空间会自动合并,这意味着可以定义多个同名的命名空间。
  2. 命名空间只能在全局定义!!

  3. `using namespace`  不等于取消命名空间, 影响的是代码编译时候查找该变量的规则(即在指定命名空间和全局变量中寻找), 比如在使用`using namespace std`后, 依然可以使用 `std :: cout` 来使用 `cout`

二、缺省参数

C++ 的缺省参数(也叫默认参数)是指在函数声明或定义时,给某些参数提供一个默认值。这样在调用函数时,如果不传递这些参数,函数会自动使用默认值。比如下面这段代码:

#include<iostream>
using namespace std;

// a = 0 b = 1 c = 2即为默认值,函数传参时可以选择不传值
void Func(int a = 0, int b = 1, int c = 2) 
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;
}


int main()
{
	cout << "Func(1, 2)\n";
	Func(1, 2);
	cout << endl;
	cout << "Func()\n";
	Func();

	return 0;
}

 

1.缺省参数分类

1.1全缺省参数

void Func(int a = 10, int b = 20, int c = 30)

1.2半缺省参数

void Func(int a, int b = 10, int c = 20)

2.使用缺省参数的注意事项

2.1申明缺省参数时从右到左

缺省参数必须从右到左依次出现,例如,不能先给 a 指定默认值而不给 b 默认值。

// 错误
void func(int a = 5, int b);

// 正确
void func(int a, int b = 10);

2.2传递参数时从左到右

不存在不连续的缺省值,即 例如在传参时不能省略第一个参数,而给出第二个参数

#include<iostream>
using namespace std;

void Func(int a = 0, int b  = 1, int c = 2) // a = 0 是舔狗 没人的时候它就上
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;
}


int main()
{
	Func(, 2, 3); //这样是不正确的!

	return 0;
}

 

2.3如果申明和定义分离,则只在声明中写缺省参数

如果函数在头文件中声明并在源文件中定义,则缺省参数不能在函数声明和定义中同时出现,所以在函数声明的时候给缺省参数, 定义的时候不给缺省参数。

因为如果声明与定义位置同时出现,恰巧两个位置提供的值不同,编译器就无法确定到底该用哪个缺省值。

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

这一点显然,给出的缺省值一定是一个固定的值,而不是一个变化的值,否则这个缺省值将毫无意义

三、函数重载

1.什么是函数重载

C++ 的函数重载是指在同一个作用域中,可以定义多个同名但参数不同的函数。编译器会根据调用时的实参类型和数量来决定调用哪个函数。这使得程序更具灵活性和可读性。

或许你已经发现了,在C++中,`std::cout` 不需要像 `printf()` 一样给定参数类型,它能自动判断参数类型输出,这其实就是一种函数重载。

在C语言中,由于不存在函数重载,我们只能通过区分函数名称来处理不同类型的数据

void printInt(int i) 
{
    printf("%d", i);
}

void printDouble(double f) 
{
    printf("%f", f);
}

void printString(char s[]) 
{
    printf("%s", s);
}

有了函数重载之后: 

void print(int i) 
{
    cout << "整数: " << i << endl;
}

void print(double f) 
{
    cout << "浮点数: " << f << endl;
}

void print(string s) 
{
    cout << "字符串: " << s << endl;
}

int main() {
    print(10);          // 调用 print(int)
    print(3.14);        // 调用 print(double)
    print("Hello");     // 调用 print(string)
    return 0;
}

我们只需定义一个函数名 print,根据不同的参数类型调用不同的实现,代码更简洁易读。 

2.构成函数重载的关键点

  1. 函数名相同:所有重载函数必须有相同的名字。        

    但注意,函数重载强调在同一个作用域中,所以两个不同命名空间的同名函数不构成函数重载

  2. 参数不同:重载函数的参数类型、个数或顺序至少有一个不同
  3. 返回类型:返回类型可以不同,但仅靠返回类型不同不能构成重载。

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Polar Web【简单】upload

Polar Web【简单】upload Contents Polar Web【简单】upload思路EXPPythonGo 运行&总结 思路 如题目所说&#xff0c;本题考查的是文件上传漏洞的渗透技巧。 打开环境&#xff0c;发现需要上传的是图片文件&#xff0c;故考虑使用截取数据包进行数据修改进行重放。在重发器…

Java面向对象-方法的重写、super

Java面向对象-方法的重写、super 一、方法的重写二、super关键字1、super可以省略2、super不可以省略3、super修饰构造器4、继承条件下构造方法的执行过程 一、方法的重写 1、发生在子类和父类中&#xff0c;当子类对父类提供的方法不满意的时候&#xff0c;要对父类的方法进行…

蓝牙安全入门——两道CTF题目复现

文章目录 蓝牙安全入门题目 low_energy_crypto获取私钥解密 题目 蓝牙钥匙的春天配对过程配对方法密钥分发数据加密安全漏洞和保护实际应用实际应用 蓝牙安全入门 &#x1f680;&#x1f680;最近一直对车联网比较感兴趣&#xff0c;但是面试官说我有些技术栈缺失&#xff0c;所…

一文带你轻松掌握Java数组定义和声明

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

【Redis】解决 Redis 运行在 Protected Mode 下的 DENIED 错误:消除 Redis 受保护模式的完美方案

【Redis】解决 Redis 运行在 Protected Mode 下的 DENIED 错误&#xff1a;消除 Redis 受保护模式的完美方案 大家好 我是寸铁&#x1f44a; 总结了一篇【Redis】解决 Redis 运行在 Protected Mode 下的 DENIED 错误&#xff1a;消除 Redis 受保护模式的完美方案✨ 喜欢的小伙伴…

优质免费的 5 款翻译 API 接口推荐

当谈到翻译API时&#xff0c;我们通常指的是一种编程接口&#xff0c;它允许开发者将文本从一种语言翻译成另一种语言。这些API通常由专业的翻译服务提供商提供&#xff0c;如谷歌翻译 API、实时翻译API、腾讯翻译API、DeepL翻译API、Azure翻译API等。 这些API通常提供多种语言…

【Linux文件篇】优化文件读写,加速数据处理策略——缓冲区

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 前言&#xff1a;我们已经复习了C语言中的接口&#xff0c;并且学习了许多文件系统调用&#xff0c;了解了文件描述符以及重定向。今天我们继续学习文件缓冲区的相关内容。 缓冲区 在学习C语言时&#xff0c;我们经常…

codeforce round951 div2

A guess the maximum 问题&#xff1a; 翻译一下就是求所有相邻元素中max - 1的最小值 代码&#xff1a; #include <iostream> #include <algorithm>using namespace std;const int N 5e4;int a[N]; int n;void solve() {cin >> n;int ans 0x3f3f3f3f;…

贪心算法06(leetcode738,968)

参考资料&#xff1a; https://programmercarl.com/0738.%E5%8D%95%E8%B0%83%E9%80%92%E5%A2%9E%E7%9A%84%E6%95%B0%E5%AD%97.html 738. 单调递增的数字 题目描述&#xff1a; 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。…

MySQL普通表转换为分区表实战指南

码到三十五 &#xff1a; 个人主页 引言 本文将详细指导新手开发者如何将MySQL中的普通表转换为分区表。分区表在处理庞大数据集时展现出显著的性能优势&#xff0c;不仅能大幅提升查询速度&#xff0c;还能有效简化数据维护工作。通过掌握这一技巧能够更好地应对数据密集型应…

【Bazel入门与精通】 rules之属性

https://bazel.build/extending/rules?hlzh-cn#attributes Attributes An attribute is a rule argument. Attributes can provide specific values to a target’s implementation, or they can refer to other targets, creating a graph of dependencies. Rule-specifi…

【会议推荐|权威主办】2024年人工智能和机械技术应用国际学术会议 (AIMTA 2024)

2024年人工智能和机械技术应用国际学术会议 &#xff08;AIMTA 2024&#xff09; 2024 International Academic Conference on Artificial Intelligence and Mechanical Technology Applications 【大会信息】 大会地点&#xff1a;西安 大会官网&#xff1a;http://www.icaimt…

springCloudAlibaba之服务熔断组件---sentinel

sentinel组件学习 sentinel学习sentinel容错机制使用代码方式进行QPS流控-流控规则初体验使用SentinelResource注解进行流控 通过代码方式设置降级规则-降级规则初体验sentinel控制台部署客户端整合服务端 springcloud整合sentinelQPS流控规则并发线程数-流控规则BlockExceptio…

kettle从入门到精通 第六十七课 ETL之kettle 再谈kettle阻塞,阻塞多个分支的多个步骤

想真正学习或者提升自己的ETL领域知识的朋友欢迎进群&#xff0c;一起学习&#xff0c;共同进步。由于群内人员较多无法直接扫描进入&#xff0c;公众号后台加我微信入群&#xff0c;备注kettle。 场景&#xff1a;ETL沟通交流群内有小伙伴反馈&#xff0c;如何多个分支处理完…

QT 使用资源文件的注意点

不要存放没有使用的资源文件 即使在代码中没有使用到的资源文件&#xff0c;也会编译到执行文件或者DLL里面去这样会增大它的体积。如下 在代码没有使用这个资源文件(10.4M的2k图片)&#xff0c;但是编译出来的程序有 12M左右的大小 1 假设我们有一个比较复杂的项目&#…

vAttention:用于在没有Paged Attention的情况下Serving LLM

文章目录 0x0. 前言&#xff08;太长不看版&#xff09;0x1. 摘要0x2. 介绍&背景0x3. 使用PagedAttention模型的问题0x3.1 需要重写注意力kernel0x3.2 在服务框架中增加冗余0x3.3 性能开销0x3.3.1 GPU上的运行时开销0x3.3.2 CPU上的运行时开销 0x4. 对LLM服务系统的洞察0x5…

【UML用户指南】-13-对高级结构建模-包

目录 1、名称 2、元素 3、可见性 4、引入与引出 用包把建模元素安排成可作为一个组来处理的较大组块。可以控制这些元素的可见性&#xff0c;使一些元素在包外是可见的&#xff0c;而另一些元素要隐藏在包内。也可以用包表示系统体系结构的不同视图。 狗窝并不复杂&#x…

《python程序语言设计》2018版第5章第35题求完全数,解题经历,我认为的正确代码放在最后

5.35从4月开始一直到成功&#xff0c;此文章将所有的记录和不同阶段代码展现给大家。但是没有配图&#xff0c;我最后成功的代码放在了最后。 2024.04.15 05.35.01version 求完整数&#xff0c;这个让我突然有点蒙。我什么时候能求完整数呢&#xff1f;&#xff1f; 正因子之和…

linux 网桥学习

前言&#xff1a; 本文来学习一下linux网桥概念和网桥配置 1. linux网桥概念 网桥&#xff0c;类似于中继器&#xff0c;连接局域网中两个或者多个网段。它与中继器的不同之处就在于它能够解析它收发的数据&#xff0c;读取目标地址信息&#xff08;MAC&#xff09;&#xff…

QSqlDatabase、QSqlQuery、QSqlRecord、Sqlite用法

使用QSqlDatabase、QSqlQuery、QSqlRecord、Sqlite数据库实现一个简单的界面查询 1. 创建Sqlite数据库&#xff0c;表 mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include "QSqlDatabase" #include "QSqlQuery&q…