002 C++基础篇

前言

大家好,本文将会向您介绍C++的命名空间、缺省/半缺省参数、函数重载相关知识

命名空间

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存
在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,
以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}
中即为命名空间的成员。
我们先看一个程序

#include <stdio.h>
#include <stdlib.h>
int rand = 0;
int main()
{
	printf("%d", rand);
	return 0;
}

error: “rand”: 重定义;以前的定义是“函数”
那是因为头文件<stdlib.h>中定义了一些标准库函数,其中包括rand()函数用于生成随机数。在全局作用域中,全局变量名rand与<stdlib.h>中定义的rand函数名冲突

默认情况下:变量只会在全局中查找,而不会到命名空间中查找。
在一个项目中,时常会遇到这种命名冲突的情况,如果不使用命名空间,就会导致其中的一个人需要去改一下变量名,因此我们使用命名空间来避免这种情况。
在这里插入图片描述
ps:namespace(根据自身情况命名)
{
//定义变量、函数、类型
}

域作用限定符

域作用限定符使用双冒号"::"来表示,它的一般形式是"命名空间::变量/函数/类
使用命名空间有三种格式
1、命名空间+作用域限定符 as :Fan::cat
2、部分展开——使用using将命名空间某个成员引入 as : using Fan::dog;
3、全展开——using namespace (…) as : using namespace Fan

ps:建议在代码中谨慎使用全展开命名空间。如果存在多个命名空间存在同名的标识符也会造成命名冲突等情况。最好的做法是只引入需要的标识符,以避免命名冲突、不可预测的行为和提高代码的可读性。

//命名空间中可以定义变量、函数、类型
namespace Fan
{
	int cat = 1;
	int dog = 2;
	int Add(int cat, int dot)
	{
		int ret = cat + dog;
		return ret;
	}
	struct Node
	{
		struct Node* node;
		int val = 0;
	};
}
using Fan::dog;		//使用using将命名空间某个成员引入
int main()
{
	//printf("%d\n", cat); //error:未定义标识符
	printf("%d\n", Fan::cat);	//命名空间+作用域限定符
	printf("%d\n", Fan::Add(Fan::cat,Fan::dog));	//命名空间+作用域限定符
	printf("%d\n", dog);	
}
//全展开命名空间
using namespace Fan;
int main()
{

	printf("%d\n", cat);	
	printf("%d\n", Add(cat, dog));	
	printf("%d\n", dog);
}

在这里插入图片描述

缺省/半缺省参数

缺省参数

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

//缺省参数
void func1(int a = -1)
{
       cout << a << endl;
}
int main()
{
       func1();
       func1(1);
       return 0;
}

在这里插入图片描述
我们可以观察到,第一个值为-1为默认值,第二个为我们指定的参数1

半缺省参数

//半缺省参数
void func2(int a, int b = 10, int c = 20)
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;
}

int main()
{
	func2(0);
	func2(1,2,3);
	return 0;
}

在这里插入图片描述

注意:半缺省参数需要从右往左来给,不能间隔给
调用函数的时候,可以有选择地提供参数覆盖
我们可以观察到。第一次调用我们仅传了一个参数 0 ,而这个参数将会从左向右覆盖

函数重载

C++的函数重载体现在:同名函数的参数类型不同、参数顺序不同、参数个数不同

//以此为基与下面的多个func比较
void func(int i, double d)
{
	cout << "void func(int i,double d)" << endl;
}

//参数类型顺序不同
void func(double d, int i)
{
	cout << "void func(double d,int i)" << endl;
}

//参数个数不同
void func(int i)
{
	cout << "void func(int i)" << endl;
}

//参数个数不同
void func()
{
	cout << "void func()" << endl;
}

//参数类型不同
void func(char i, char d)
{
	cout << "void func(char i,char d)" << endl;
}
int main()
{
	func('a','b');
	func(1);
	func(1, 1.1);
	func(1.1, 1);
	func();
	return 0;
}

根据我们传入的参数不同,会有不同的调用结果,我们来看看调用结果
在这里插入图片描述

函数名修饰规则

C语言没有函数重载,而C++却有,原因是C语言没有函数名修饰规则,单纯以函数名调用,这导致符号表中存储的函数名会乱,如有同名函数,从而不知调用哪一个。而C++有,函数名修饰规则因编译器而异(本文基于VS2019)
但通常根据:函数名、参数类型、参数个数。注意返回类型不会影响函数名修饰规则()
将函数定义屏蔽掉我们来看看
在这里插入图片描述
观察到
void __cdecl func(int,double)" (?func@@YAXHN@Z)
void __cdecl func(double,int)" (?func@@YAXNH@Z)
void __cdecl func(int)" (?func@@YAXH@Z)
void __cdecl func(void)" (?func@@YAXXZ)
void __cdecl func(char,char)" (?func@@YAXDD@Z)
其中的差异取决于编译器的函数名修饰规则不同

小结

文本是C++入门篇,建议初学者将文中代码能够打一下然后运行重在理解。如果本文有疏漏或错误的地方还请您能指出。祝您天天开心啦!

posted @ 2023-07-21 11:03  Fan_558  阅读(3)  评论(0编辑  收藏  举报  来源