0
点赞
收藏
分享

微信扫一扫

双冒号作用运算符以及using namespace详解,你确定不来看看吗?

月半小夜曲_ 2022-04-22 阅读 68
c++

文章目录

前言

记录一些c++的基础知识,欢迎大家和我一起学习,一起进步

一、双冒号作用域运算符

通常情况下,如果程序中即存在局部变量又存在全局变量,局部变量将会获得较高的优先权,它将屏蔽全局变量,但双冒号作用域运算符可以解决局部变量和全局变量重名的问题,代码如下:

int atk = 200;
void test01()
{
	int atk = 100;

	cout << "攻击力为 : " << atk << endl;
	//双冒号 作用域运算符  ::全局作用域
	cout << "全局攻击力为 : " << ::atk << endl;
}

打印结果如下

攻击力为 : 100
全局攻击力为 : 200
请按任意键继续. . .

可以看到,当我们在变量前面加入::时,全局变量将会获得较高优先权。

二、c++命名空间(namespace)

1.用途

在程序中,名称(符号常量、变量、函数、结构、枚举、类和对象等等)可能会相互冲突,namespace可以通过控制各个标识符的作用域,使他们避免发生冲突。

2.命名空间使用语法

2.1 创建一个命名空间

namespace A{
	int a = 10;
}
namespace B{
	int a = 20;
}
void test(){
	cout << "A::a : " << A::a << endl;
	cout << "B::a : " << B::a << endl;
}

这样可以打印出每个命名中间中对应a的值

2.2 命名空间只能定义为全局变量

以下为错误写法

void test(){
	namespace A{
		int a = 10;
	}
	namespace B{
		int a = 20;
	}
	cout << "A::a : " << A::a << endl;
	cout << "B::a : " << B::a << endl;
}

2.3命名空间可以嵌套命名空间

代码如下

namespace A{
	int a = 10;
	namespace B{
		int a = 20;
	}
}
void test(){
	cout << "A::a : " << A::a << endl;
	cout << "A::B::a : " << A::B::a << endl;
}

2.4命名空间是开放的

命名空间是开放的,可以随时把新成员加入到命名空间中去

namespace A{
	int a = 10;
}

namespace A{
	void func(){
		cout << "hello namespace!" << endl;
	}
}

void test(){
	cout << "A::a : " << A::a << endl;
	A::func();
}

2.5 无命名空间

无命名空间,相当于给空间里面的标识符都加上了static,使其为内部链接,只能在本文件中使用

namespace{
	
	int a = 10;
	void func(){ cout << "hello namespace" << endl; }
}
void test(){
	cout << "a : " << a << endl;
	func();
}

2.6 命名空间可以起别名

我们可以随时对命名空间起别名,就好比我们的父母给我们起小名一样

namespace veryLongName{
	
	int a = 10;
	void func(){ cout << "hello namespace" << endl; }
}

void test(){
	namespace shortName = veryLongName;
	cout << "veryLongName::a : " << shortName::a << endl;
	veryLongName::func();
	shortName::func();
}

三、using声明和using编译指令

1.using声明指定标识符

我们可以通过using声明来指定特定命名空间的标识符

namespace KingGlory
{
	int sunwukongId = 10;
}

void test01()
{
	int sunwukongId = 20;

	//using 声明  注意避免二义性问题
	//写了using声明后  下面这行代码说明以后看到的sunwukongId 是用KingGlory下的
	//但是  编译器又有就近原则
	//二义性
	using KingGlory::sunwukongId;

	cout << sunwukongId << endl;
}

该代码会发生报错,因为写了using声明后,以后编译器默认sunwukongId是用 KingGlory下的,和编译器的局部变量就近原则产生了冲突,故程序会报错,在写代码时,我们要尽量避免二义性的发生。

using namespace std;

namespace KingGlory
{
	int sunwukongId = 10;
}

void test01()
{
	int sunwukongId = 20;

	using namespace KingGlory;

	cout << sunwukongId << endl;
}

这样写将不会发生报错,using namespace KingGlory;只代表打开KingGlory这个房间,不对里面的标识符进行指定,编译器遵循就近原则。

2.using 编译指令

每次使用using都好比打开一个房间,using编译指令使整个命名空间的标识符可用.

namespace A{
	int paramA = 20;
		int paramB = 30;
	void funcA(){ cout << "hello funcA" << endl; }
	void funcB(){ cout << "hello funcB" << endl; }
}
void test01(){
	using namespace A;
	cout << paramA << endl;
	cout << paramB << endl;
	funcA();
	funcB();

	//不会产生二义性
	int paramA = 30;
	cout << paramA << endl;
}

前面说过,这样写编译器遵行就近原则,不会产生二义性,而像下面这样写则会出现问题


namespace B{
	int paramA = 20;
	int paramB = 30;
	void funcA(){ cout << "hello funcA" << endl; }
	void funcB(){ cout << "hello funcB" << endl; }
}

void test02(){
	using namespace A;
	using namespace B;
	//二义性产生,不知道调用A还是B的paramA
	//cout << paramA << endl;
}

多次使用using编译指令,同时打开多个房间将会发生二义性

总结

以上就是今天要讲的内容,本文仅仅简单介绍了c++的一些基础知识,希望能给大家带来帮助。

举报

相关推荐

0 条评论