C++ 命名空间

news/2024/11/23 12:55:35/

假设这样一种情况,当一个班上有两个名叫 Zara 的学生时,为了明确区分它们,我们在使用名字之外,不得不使用一些额外的信息,比如他们的家庭住址,或者他们父母的名字等等。

同样的情况也出现在 C++ 应用程序中。例如,您可能会写一个名为 xyz() 的函数,在另一个可用的库中也存在一个相同的函数 xyz()。这样,编译器就无法判断您所使用的是哪一个 xyz() 函数。

因此,引入了命名空间这个概念,专门用于解决上面的问题,它可作为附加信息来区分不同库中相同名称的函数、类、变量等。使用了命名空间即定义了上下文。本质上,命名空间就是定义了一个范围。

我们举一个计算机系统中的例子,一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名。

定义命名空间

命名空间的定义使用关键字 namespace,后跟命名空间的名称,如下所示:

namespace namespace_name {

// 代码声明

}

为了调用带有命名空间的函数或变量,需要在前面加上命名空间的名称,如下所示:

name::code; // code 可以是变量或函数

让我们来看看命名空间如何为变量或函数等实体定义范围:

 当上面的代码被编译和执行时,它会产生下列结果:

Inside first_space
Inside second_space

using 指令

您可以使用 using namespace 指令,这样在使用命名空间时就可以不用在前面加上命名空间的名称。这个指令会告诉编译器,后续的代码将使用指定的命名空间中的名称。

当上面的代码被编译和执行时,它会产生下列结果:

Inside first_space

using 指令也可以用来指定命名空间中的特定项目。例如,如果您只打算使用 std 命名空间中的 cout 部分,您可以使用如下的语句:

using std::cout;

随后的代码中,在使用 cout 时就可以不用加上命名空间名称作为前缀,但是 std 命名空间中的其他项目仍然需要加上命名空间名称作为前缀,如下所示:

 当上面的代码被编译和执行时,它会产生下列结果:

std::endl is used with std!

using 指令引入的名称遵循正常的范围规则。名称从使用 using 指令开始是可见的,直到该范围结束。此时,在范围以外定义的同名实体是隐藏的。

不连续的命名空间

命名空间可以定义在几个不同的部分中,因此命名空间是由几个单独定义的部分组成的。一个命名空间的各个组成部分可以分散在多个文件中。

所以,如果命名空间中的某个组成部分需要请求定义在另一个文件中的名称,则仍然需要声明该名称。下面的命名空间定义可以是定义一个新的命名空间,也可以是为已有的命名空间增加新的元素:

namespace namespace_name {

// 代码声明

}

嵌套的命名空间

命名空间可以嵌套,您可以在一个命名空间中定义另一个命名空间,如下所示:

 namespace namespace_name1 {

// 代码声明

namespace namespace_name2 {

// 代码声明

}

}

你可以通过使用 :: 运算符来访问嵌套的命名空间中的成员: 

 在上面的语句中,如果使用的是 namespace_name1,那么在该范围内 namespace_name2 中的元素也是可用的,如下所示:

 

 当上面的代码被编译和执行时,它会产生下列结果:

Inside second_space
  • 补充:

关于命名空间内变量和函数及全局变量的使用和作用域:

#include <iostream>
using namespace std;
namespace A
{int a = 100;namespace B            //嵌套一个命名空间B{int a =20;}
}int a = 200;//定义一个全局变量int main(int argc, char *argv[])
{cout <<"A::a ="<< A::a << endl;cout <<"A::B::a ="<<A::B::a << endl;cout <<"a ="<<a << endl;cout <<"::a ="<<::a << endl;int a = 30;cout <<"a ="<<a << endl;cout <<"::a ="<<::a << endl;return 0;
}

结果:

A::a =100  
A::B::a =20
a =200      //全局变量a
::a =200
a =30       //局部变量a
::a =200    

:全局变量 a 表达为 ::a,用于当有同名的局部变量时来区别两者。

补充关于 using 的错误事例:

#include <iostream>
using namespace std;
namespace A
{int a = 100;int fun(){cout<<"a = "<<a<<endl;}namespace B            //嵌套一个命名空间B{int a =20;int fun(){cout<<"a = "<<a<<endl;}}
}int main(int argc, char *argv[])
{cout<<a<<endl;fun();return 0;
}

这样会出错:会显示 a 变量和 fun 函数 “was not declared in this scope”,即找不到这个 a 和 fun 函数。

解决办法: 用 using 来告诉编译器用到的是哪个命名空间内的内容。在 main() 上面加 using namespace A; 或者 using namespace A::B; 。这样就可以使用其中的 a 和 fun()。但是不能同时使用,因为这样也会导致编译出错,编译器器不知道要去使用哪个 a 和 fun()。

  • 补充一个命名空间冲突的情况:
#include <iostream>using namespace std;
namespace A {int a = 100;namespace B            //嵌套一个命名空间B{int a = 20;}
}int a = 200;//定义一个全局变量int main(int argc, char *argv[]) {cout << "A::a =" << A::a << endl;        //A::a =100cout << "A::B::a =" << A::B::a << endl;  //A::B::a =20cout << "a =" << a << endl;              //a =200cout << "::a =" << ::a << endl;          //::a =200using namespace A;cout << "a =" << a << endl;     // Reference to 'a' is ambiguous // 命名空间冲突,编译期错误cout << "::a =" << ::a << endl; //::a =200int a = 30;cout << "a =" << a << endl;     //a =30cout << "::a =" << ::a << endl; //::a =200//即:全局变量 a 表达为 ::a,用于当有同名的局部变量时来区别两者。using namespace A;cout << "a =" << a << endl;     // a =30  // 当有本地同名变量后,优先使用本地,冲突解除cout << "::a =" << ::a << endl; //::a =200return 0;
}

 


http://www.ppmy.cn/news/671292.html

相关文章

一、微服务和SpringCloud简介

1.微服务简介 微服务(不是一个框架 而是一种架构思想)&#xff0c;是著名的 oo &#xff08;面向对象&#xff0c; ObjectOriented &#xff09;专家 Martin Fowler 提出来的&#xff0c;它是用来描述将软件应用程序设计为独立部署的服务的一种特殊方式。 最近两年&#xff0…

手机GPU是什么

我们听说过电脑GPU&#xff0c;常常用于玩游戏&#xff0c;处理图形软件等&#xff0c;获得更加好的性能&#xff0c;但是我们很少听说手机GPU&#xff0c;我们在买手机的时候有没有关注过GPU这个概念呢&#xff1f;还是我们在购买手机的时候只考虑到性价比&#xff0c;尺寸&am…

Adreno GPU详细介绍

Adreno GPU详细介绍 Adreno GPU是美国Qualcomm为移动平台设计的集成GPU。支持最先进的移动API&#xff0c;同时具有优异的性&#xff0c;应用于对带宽、功耗、散热等方面都有限制的移动芯片。Adreno GPU支持任意复杂的API&#xff0c;比如OpenGL ES(2.0、3.0、3.1等)、OpenCL、…

SSM网上商城

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:Java韩立 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 SSM网上商城,java项目。 eclipse和idea都能打开运行。 推…

Java 的拷贝(深拷贝、浅拷贝)

在对象的拷贝中&#xff0c;很多初学者可能搞不清到底是拷贝了引用还是拷贝了对象。在拷贝中这里就分为引用拷贝、浅拷贝、深拷贝进行讲述。 引用拷贝 引用拷贝会生成一个新的对象引用地址&#xff0c;但是两个最终指向依然是同一个对象。如何更好的理解引用拷贝呢&#xff1…

php获取判断图片大小,php获取图片详细信息(宽 高 格式 大小)

function getImageInfo($img) //$img为图像文件绝对路径 { $img_info getimagesize($img); switch ($img_info[2]) { case 1: $imgtype "GIF"; break; case 2: $imgtype "JPG"; break; case 3: $imgtype "PNG"; break; } $img_type $imgtyp…

npy文件的读出与修改

npy 文件用于存储重建ndarray 所需的数据、图形、dtype 和其他信息。 常用的IO 函数有: load() 和save() 函数是读写文件数组数据的两个主要函数,默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为. npy 的文件中。 1.首先自己写一个.npy文件,使用np.save(‘test.…

华为鸿蒙与海尔,国产家电巨头力挺华为,强强联合,为鸿蒙系统开疆拓土

鸿蒙依托美的电器&#xff0c;直接进入国际市场 在众多意想不到的收获当中&#xff0c;最让华为期许便是国际市场。国内市场有人支持鸿蒙&#xff0c;但国外市场被苹果和安卓占有&#xff0c;没有一系列卓越的品牌去刺激&#xff0c;是很难找到自己立足的市场。 美的国际形象良…