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

2024-06-11 05:12

本文主要是介绍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. 返回类型:返回类型可以不同,但仅靠返回类型不同不能构成重载。

 

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



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

相关文章

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

SpringMVC获取请求参数的方法

《SpringMVC获取请求参数的方法》:本文主要介绍SpringMVC获取请求参数的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下... 目录1、通过ServletAPI获取2、通过控制器方法的形参获取请求参数3、@RequestParam4、@

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

MySQL高级查询之JOIN、子查询、窗口函数实际案例

《MySQL高级查询之JOIN、子查询、窗口函数实际案例》:本文主要介绍MySQL高级查询之JOIN、子查询、窗口函数实际案例的相关资料,JOIN用于多表关联查询,子查询用于数据筛选和过滤,窗口函... 目录前言1. JOIN(连接查询)1.1 内连接(INNER JOIN)1.2 左连接(LEFT JOI

C++ vector的常见用法超详细讲解

《C++vector的常见用法超详细讲解》:本文主要介绍C++vector的常见用法,包括C++中vector容器的定义、初始化方法、访问元素、常用函数及其时间复杂度,通过代码介绍的非常详细,... 目录1、vector的定义2、vector常用初始化方法1、使编程用花括号直接赋值2、使用圆括号赋值3、ve

MySQL中FIND_IN_SET函数与INSTR函数用法解析

《MySQL中FIND_IN_SET函数与INSTR函数用法解析》:本文主要介绍MySQL中FIND_IN_SET函数与INSTR函数用法解析,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一... 目录一、功能定义与语法1、FIND_IN_SET函数2、INSTR函数二、本质区别对比三、实际场景案例分

Spring Boot项目部署命令java -jar的各种参数及作用详解

《SpringBoot项目部署命令java-jar的各种参数及作用详解》:本文主要介绍SpringBoot项目部署命令java-jar的各种参数及作用的相关资料,包括设置内存大小、垃圾回收... 目录前言一、基础命令结构二、常见的 Java 命令参数1. 设置内存大小2. 配置垃圾回收器3. 配置线程栈大小

如何高效移除C++关联容器中的元素

《如何高效移除C++关联容器中的元素》关联容器和顺序容器有着很大不同,关联容器中的元素是按照关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的,本文介绍了如何高效移除C+... 目录一、简介二、移除给定位置的元素三、移除与特定键值等价的元素四、移除满足特android定条件的元

Python获取C++中返回的char*字段的两种思路

《Python获取C++中返回的char*字段的两种思路》有时候需要获取C++函数中返回来的不定长的char*字符串,本文小编为大家找到了两种解决问题的思路,感兴趣的小伙伴可以跟随小编一起学习一下... 有时候需要获取C++函数中返回来的不定长的char*字符串,目前我找到两种解决问题的思路,具体实现如下:

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序