精华内容
下载资源
问答
  • 命名空间及匿名命名空间

    千次阅读 2013-10-10 10:44:11
    1. 使用命名空间的必要性  在一个大的项目中,当多时合作时,多个人编写的库头文件中,不可以避免的存在变量名相同的冲突,特别都是作为全局变量存在的时候,这种冲突就更为明显,如何解决这种冲突?方法就是使用...

    把命名空间单独提出来描述是因为:命名空间的功能几乎和前缀是一致的。

    1.       使用命名空间的必要性

              在一个大的项目中,当多时合作时,多个人编写的库头文件中,不可以避免的存在变量名相同的冲突,特别都是作为全局变量存在的时候,这种冲突就更为明显,如何解决这种冲突?方法就是使用命名空间。

              比如说,每个人所定义的变量,都以他自己的名字的缩写为前缀,假如名字缩写为sxl,则定义一个全局变量CMD,则应该该为sxlCMD,但是这种组合方式从旁观者的角度看来是不顺眼的。为了解决这种问题,则使用命名空间。把sxl定义为命名,所以属于它的范围内的变量及函数都属于这个名字的空间。

    命名空间的定义方法:

    命名空间的使用方法为:

    在编写头文件时,一个良好的风格,就是尽量使用命名空间。

    有名字的命名空间是external linkage的,而匿名的命名空间是internal linkage的。

    2.       命名空间的使用规则

    1.  命名空间的使用(using namespace xxx)可以在函数内使用,而命名空间只限制在该函数内。

    2.  C++手册中规定,除了命名空间std外,其它的命名空间都可被修改(扩展)。如果修改命名空间std,则将导致不可预料的行为(undefined behavior)。但是在VS2008中验证,编译器并不阻止用户扩展std命名空间—可以通过编译。只能说明扩展命名空间导致的不可预料的后果由程序员承担。

    3.  不要在头文件中使用匿名命名空间,提倡在cpp/cc文件中使用匿名命名空间来代替static关键字。(!!尤其是绝对不要在头文件的匿名命名空间中定义类,原因见参见匿名命名空间的特殊点知识)

    4.  不能在命名空间中重载new/delete操作符,因为这很容易导致调用二义性。

    5.  对于长串的层级命名空间,如果每次都顺序列出命令空间,则使用不方便,可以使用命名空间的别名。如:

    namespace curSpace=std::tr1::regex_constants;

    using namespace curSpace;

    6.  使用命名空间别名时,只能一次性赋值,不能重赋值。这个类似于变量的引用:只能定义时给引用赋值,不能给引用改变引向。

    namespace curSpace=std::tr1::regex_constants;

    curSpace= std::tr1;                // error C2882:illegal use of namespaceidentifier in expression

    7.            命名空间的其它用法

    命名空间除常见的功能用于识别同名变量外/函数/类外,还有一个用法:版本控制:程序的有些功能,在不同的版本中,可能功能是不一样的,如果使用if/else来控制,有时可读性不太好,则这时可以使用命名空间。

     

    8.  命名空间的开销

    编译器通常函数的原型,函数的类名,函数的空间名来生成/定位一个独一无二的函数名字,这些查找都是静态的(在编译期执行)。因此,层次性的多级命名空间/命名空间切换只会带来编译时一些开销,而不会带来运行时的时间与内存开销。

    因此,使用命名开销是值得提倡的。(这种微小的编译开销是值得的)

    9.  由命名空间引起的include用法的变革。

    由于命名空间的原因,在新C++中,提倡引用头文件不再带.h。引用C头文件也不带.h,但是带前缀c。例如:

    #include <cstdio>                 //引用C头文件c为前缀

    #include<cassert>               //引用C头文件c为前缀

    #include <array>                               //引用C++头文件

    这是因为,C++会自动把许多声明归到std命名空间中去,而把C头文件中的声明加入到全局命名空间中去。(全局命名空间是不提倡的)

    C++仍然支持include的各种老的用法,但是不再提倡。

     

     

    3.       匿名命名空间的特殊点


    匿名命名空间(unnamed namespace, anonymousnamespace)

    匿名命名空间的一些特殊点会影响到它的使用,所以有必要单独列出来。

    通常除了类的静态成员函数和静态数据成员外,其它的static需求都提倡使用匿名命名空间来代替。

    Ø  代替static用法

    在标准C中,如果期望一个变量或者一种函数只能被本源文件(同个translation unit)使用,通常的做法是使用static来修饰这个变量/函数,来保证这个变量/函数具有内部链接(internal linkage)。这种技术称为信息隐藏。

    在C++中,仍然支持这种做法,但是已经不提倡,C++只提倡static仅仅用于修饰类成员,不再提倡用static来修饰非类成员。在以后的编译器中,可能会对使用static来修饰非类成员的方式给出编译警告。

     

    staticVarstaticFunc只能在本源文件中使用,不同的源文件中可以使用同名变量及函数,它们相互隐藏,不会产生命名冲突。

    注意:在VS2008上验证,只有顶级匿名命名空间才具有隐藏效果(不知道是C++语言是这么规定的,还是VS编译器的bug)。如果一个子匿名命令空间是定义在一个命名的命名空间中,则该匿名命令空间中定义的类和实例都可被其它源文件访问。

    Ø  不要在.h文件中使用匿名命名空间

    提倡在cpp/c源文件中使用unnamed namespace,不要(不提倡)在.h文件中什么匿名命令空间,因为其将生成大量不被使用类型或者数据---这些数据不是副本,是全局唯一的(原因见下面)。

    这里重提一下:.h文件与.cpp文件。.h文件不是编译单元,所以不能直接编译.h文件;.cpp/.cc文件才是编译单元,编译器可以直接编译.cpp/.cc文件。那么如果一个.cpp文件include了.h文件,是什么效果呢?直白的意思就是:把所有(直接/间接)include的.h的文件内容直接复制到该.cpp文件中,再对该.cpp文件编译。这就意味着,如果在一个头文件中定义了unnamed namespace,那么所有include该.h的编译单元(.cpp/.cc文件),都会完全包含该.h文件中的所有内容,那么,一个.cpp/.cc中包含的匿名空间里的数据,它自己当然能访问了。无论它具有的是内部链接属性,还是外部链接属性,都不影响访问。(除非对访问对象有链接属性要求的场景:比如模块的非类型参数-数据实参)。

    原因分析:虽然unnamed namespce是internal linkage,但是如果其在.h文件中使用,并且该.h文件被多个.cpp文件引用的时候,编译器会为这个匿名的命名空间在不同的.cpp中生成不同的唯一的空间名字(即开发者使用匿名命名空间,但是编译器编译时仍然给它生成了一个唯一的名字)。

    比如:对于匿名命名空间中的类型struct LocalType,其在编译单元src1.cpp的内部名字是::a0b2de::LocalType,在编译单元src2.cpp的内部名字是::d3fe23d:: LocalType。

    对于开发者来说,看到的只是LocalType,但是对于编译器来说,其看到的是两个不同的类型(因为其在不同的命名空间中)。所以意味着当该.h文件被include时,其在每个cpp文件中有一份命名空间不同的同名类型LocalType。如果在该匿名命令空间中定义了类型,那么意味着潜在地存在错误。考虑下面这种情况。

    在匿名命名空间中定义了一个新的用户类型,如果这个匿名命名空间在头文件中,那么其将被inlcude到各个源文件并且一变多成为多个不同的类型。

    在不同的(cpp/cc)源文件中,用户看到的同一个类名,但是在不同的translation unit中,编译器为它们添加了不同的C++修饰名(命名空间),即在不同的编译单元中,它们是不同的类型。如果这种情况下,需要使用type_info类的信息进行比较,就会得出错误的结果。代码:

    a) 在头文件中定义匿名命名空间

     

    b) 分别在两个cpp文件中使用Type2Type类型

    在第一个源文件中

     

     

    在第二个源文件中

     

    其实在这两个源文件中使用的LocalType类并不是同一个类—编译器在各自的编译单元里为它们添加了不同的C++修饰符。

    C ) 测试代码

     

     

    D) 测试结果

    在调试器中观察其值:

     

    可以看到除了这两个类的基本名字相同外,其原始名字(即修饰名)和type_info的比较结果都是不同的(type_info使用原始名字进行比较)。

    原始名字中的不同(黄色)部分,就是编译器为不同编译单元中的LocalType生成的匿名空间的空间名(参考"C++修饰名"知识点),由此证明在上面两个源文件中(init_1.cpp/init_2.cpp)使用的LocalType并不是同一个类。

    (其中编译器生成的匿名空间名字猜测是文件路径的某种编码信息,比如把第二个源文件的文件名由init_2.cpp改成init_2_ex.cpp,则其相应的黄色部分变成?A0xafb6ef69; 而改动init_2.cpp的文件内容,重新编译,则黄色部分的值并不改变。即匿名空间的修饰名包含源文件路径信息)

     

    Ø  在模板元设计中小心使用匿名命名空间

    匿名空间具有内部链接属性,其内部定义的函数/类型/变量/常量在不同的编译单元都是不同的,所以在进行模板设计时,尤其要小心,以防止传入的类型参数来自于不同编译单元的匿名命名空间,这样开发者字面意思看到的是同一类型,但是模板元逻辑处理中,竟然是不同的类型,很容易被认为是编译器的bug。

    出于这个目的,我们可以考虑在模板元设计中禁止使用匿名命名空间。

    这其实是上一条规则中的一个实例:因为模板元代码都是在.h文件中的,而"不要在.h文件中使用匿名命名空间"

     

    Ø  无法引用定义在匿名命名空间中其它编译单元里的类型和数据。

    正是因为上述的原因(编译器为不同编译单元里的匿名命名空间生成了不同的名字),所以我们无法引用定义在其它编译单元的匿名命名空间中定义的类型和数据,哪怕这些类型和数据来自于同一个.h文件――在这种情况下,我们引用的类型和名字,并不是我们逻辑上期望的那个类型和名字,这即意味着一个实现错误

     

     

     

    展开全文
  • 该用户知道如何查看网页的源代码,因此该用户查看了JS游戏背后的源代码,并意识到points变量仅位于全局命名空间中 。 当他们考虑可以达到的要点时,邪恶的假笑降临在他们的脸上! 他们决定,他们不想等待来打败一些...

    Let’s take a look at what a namespace is when it comes to building JavaScript applications and some of the benefits from using a private namespace when building your apps.

    让我们看一下在构建JavaScript应用程序时的名称空间是什么,以及在构建应用程序时使用私有名称空间的一些好处。

    Please note that this article references anonymous self-executing functions. If you’re unaware of what this is, please read this excellent article by Noah Stokes: Self-Executing Anonymous Functions or How to Write Clean Javascript. This article will go into detail about anonymous self-executing functions.

    请注意,本文引用了匿名自执行函数。 如果您不知道这是什么,请阅读Noah Stokes撰写的这篇出色的文章: 自执行匿名函数或如何编写简洁的Javascript 本文将详细介绍匿名自执行功能。

    什么是命名空间? (What is a Namespace?)

    To put it simply, a namespace is just a section of code that has its own space. When you first begin writing JS apps, you generally just type the code out and run it. This puts all of the code into what’s known as the global namespace, which contains all of the code for the window you’re working in.

    简单地说,名称空间只是具有自己空间的一段代码。 当您第一次开始编写JS应用程序时,通常只需键入代码并运行它。 这会将所有代码放入所谓的全局名称空间 ,该名称空间包含您正在使用的窗口的所有代码。

    If you keep all of your code in the global namespace, though, you can run into problems with collisions, naming conventions, etc. especially in large JS applications/games.

    但是,如果将所有代码都保留在全局名称空间中 ,则可能会遇到冲突,命名约定等问题,尤其是在大型JS应用程序/游戏中。

    Let’s take a look at an example of how using only the global namespace to develop a game is a bad idea.

    让我们看一个示例,该示例仅使用全局名称空间来开发游戏是一个坏主意。

    So, let’s say we have a game that is keep tracking of the points that the player has:

    因此,假设我们有一款持续跟踪玩家所拥有积分的游戏:

    var points = 0;

    A lot of games track points to add a competitive edge to the game. By simply typing that line into a script, we’ve created a variable named points that can track the points gained by the user.

    许多游戏都跟踪点数,以增加游戏的竞争优势。 通过简单地在脚本中键入该行,我们创建了一个名为points的变量,该变量可以跟踪用户获得的积分。

    And that’s all fine and well, but let’s say that we have a more advanced user playing the game. This user knows how to look at the source of a web page, and so this person takes a peek at the source behind the JS game and realizes that the points variable is just sitting there in the global namespace. An evil smirk descends across their face as they contemplate the points they can achieve! They decide that they don’t want to wait to beat some baddies up, or smash some mushrooms, or what have you, to rack up a bunch of points. They want their points now! Well, how does a quadrillion billion million points sound?! So, they load up the console on their favorite browser, and simply type into the console:

    一切都很好,但是,比方说,我们有一个更高级的用户在玩游戏。 该用户知道如何查看网页的源代码,因此该用户查看了JS游戏背后的源代码,并意识到points变量仅位于全局命名空间中 。 当他们考虑可以达到的要点时,邪恶的假笑降临在他们的脸上! 他们决定,他们不想等待来打败一些坏人,或者砸碎蘑菇,或者弄破你的东西来累积一分。 他们现在想要他们的观点! 那么, 万亿亿点听起来如何?! 因此,他们在自己喜欢的浏览器上加载了控制台,然后只需键入控制台即可:

    points = 34750925489459203859095480917458059034;

    Once the user hits enter, the points variable is updated in the game. Now, the user has a truly humongous, and likely unrealistic, amount of points in the game, and he can brag to his friends that no one can possibly beat his awesome score.

    用户按下Enter键后, points变量将在游戏中更新。 现在,用户在游戏中获得了真正巨大的积分,而且可能是不现实的积分,而且他可以吹嘘自己的朋友,没有人能超过他的出色分数。

    So, how do we prevent this from occurring? This is where private namespaces come into play.

    那么,我们如何防止这种情况发生呢? 这是私有名称空间起作用的地方。

    私人命名空间 (Private Namespaces)

    Private namespaces allow developers to put their code into sections (or namespaces). These sections operate independently of each other but can still read and write from the global namespace.

    私有名称空间允许开发人员将其代码放入部分(或名称空间 )中。 这些部分彼此独立运行,但仍可以从全局名称空间读取和写入。

    To break this down into simpler terms from a real life scenario, let’s say you are working in an office building. You have your own office, and you see others with their own offices. Each office is locked, and only the person who owns the office has a key to this office. Let’s also say that you have some type of new super lock that makes your office impenetrable by any other person in the building. Let’s consider the office building itself as the global namespace and each office as a private namespace. You don’t have access to anyone else’s office nor do they have access to yours. But, each one of you have access to the rest of the office building, whether that’s getting coffee, grabbing a snack, etc. Each one of you can grab something from the global namespace (or create/modify something there), but you can’t create/modify/grab anything from each other’s offices; you can only create/modify/grab from your own private namespace/office.

    为了从现实生活中将其分解为更简单的术语,假设您在办公楼中工作。 您有自己的办公室,并且看到其他人也有自己的办公室。 每个办公室都被锁定,只有拥有办公室的人才能拥有该办公室的钥匙。 假设您拥有某种新型的超级锁,可以使办公室中的任何其他人都无法穿透您的办公室。 让我们将办公楼本身视为全局命名空间 ,将每个办公楼视为私有命名空间 。 您无权访问任何其他人的办公室,也无权访问他们的办公室。 但是,你们每个人都可以访问办公楼的其余部分,无论是喝咖啡,品尝小吃等。你们每个人都可以从全局名称空间中获取某些东西(或在其中创建/修改某物),但是您可以不得从彼此的办公室创建/修改/抢劫任何东西; 您只能从自己的私有名称空间 / office创建/修改/抓取。

    实现私有命名空间 (Achieving a Private Namespace)

    So, how do we achieve this private namespace in JavaScript? Use an anonymous self-executing function! If you didn’t read the article by Noah Stokes, Self-Executing Anonymous Functions or How to Write Clean Javascript, please do so now. This article will go into detail about anonymous self-executing functions.

    那么,我们如何在JavaScript中实现这个私有名称空间 ? 使用匿名自执行功能! 如果您没有阅读Noah Stokes的文章, 自执行匿名函数或如何编写简洁的Javascript ,请立即阅读。 本文将详细介绍匿名自执行功能。

    Let’s take a look at using that points variable from earlier, but let’s separate it into a private namespace:

    让我们看一下使用早先的points变量,但让我们将其分成一个私有名称空间

    //The most common way you'll see an anonymous self-executing function
    (function () {
        var points = 0;
    })();
    
    //This is just one of many more alternative ways to use an anonymous self-executing function
    /*
    !function () {
        var points = 0;
    }();
    */

    Now, when the user gets to the page, they will be unable to open up the console in their browser and change the value of the points variable as they wish! Awesome!

    现在,当用户进入页面时,他们将无法在浏览器中打开控制台并根据需要更改points变量的值! 太棒了!

    命名空间和文档交互 (Namespace and Document Interaction)

    The above code was but one use for using an anonymous self-executing function to give code its own private namespace. Keep in mind that namespaces only affect JS code (variables/arrays/objects/etc.), not code that pertains to the document itself.

    上面的代码只是使用匿名自执行函数为代码提供自己的私有名称空间的一种用途。 请记住,名称空间仅影响JS代码(变量/数组/对象/等),而不影响与文档本身相关的代码。

    Any code within a namespace still has the same access to the HTML document, and CSS, as you would normally in the global namespace. Take a look at the next two code samples. They both perform the same functionality, and neither is more beneficial, or more efficient, than the other.

    命名空间中的任何代码仍然具有对HTML文档和CSS的相同访问权限,就像通常在全局命名空间中一样 。 看一下下面的两个代码示例。 它们都执行相同的功能,并且没有一个比另一个更有益或更有效。

    <script type="text/javascript">
        (function () {
            document.querySelector('body').style.background = 'blue';
        })();
    </script>

    is the same as:

    是相同的:

    <script type="text/javascript">
        document.querySelector('body').style.background = 'blue';
    </script>

    Keep in mind that this is just one way to use namespaces in JavaScript applications. Adapt your code to what best fits the situation at hand.

    请记住,这只是在JavaScript应用程序中使用名称空间的一种方法。 使您的代码适应最适合当前情况的代码。

    翻译自: https://www.freecodecamp.org/news/how-to-use-anonymous-functions-for-private-namespacing-in-your-javascript-apps/

    展开全文
  • 何为命名空间1.1 什么是命名空间1.2 C语言是如何解决名称冲突的1.3 命名空间如何解决问题1.4 关于语言特性的思考2.namespace的初级定义和使用2.1 同一文件内定义namespace2.2 同一文件内使用namespace2.3 不同C文件...

    1. 何为命名空间

    1.1 什么是命名空间

    namespace,中文就是命名空间,同时这也是C++语言中的一个关键字。命名空间是C++引入的一种彻底地、很方便地解决全局变量和函数名冲突的机制。变量分全局变量和局部变量,所谓全局,就是定义在函数之外的,局部变量则一般定义在函数体内部。函数则全部是全局性质的。

    C语言没有命名空间,但是C++及之后的JavaPython等高级语言都有,并且在C++的基础上有更好的改进。

    理解命名空间的关键点有2个:

    • 1.命名空间是如何解决名称冲突的。
    • 2.使用了命名空间后如何合法地访问变量。

    1.2 C语言是如何解决名称冲突的

    首先要知道,名称冲突是一个客观存在。在大型的C语言项目(比如Linux内核)中会有很多C文件,全局变量和函数都是extern链接属性(其他文件可以通过声明来跨文件访问),一个项目是一个单体程序,项目中的全局变量和函数理应能互相访问,因此很容易发生名称冲突。

    C语言中解决名称冲突的办法是:

    • 1.同一个C文件不要太大,由一个人写。
    • 2.每个C文件(或几个C文件构成的一个模块)中所有全局变量和函数前加统一的唯一前缀。比如写SD卡模块的函数名都叫sd_func(),写串口模块的都叫uart_func()
    • 3.不需要文件外访问的全局变量和函数前面都加staticstatic修饰全局变量和函数的作用就是将该变量和函数的可见范围从externallocal,即仅本文件内可见,其他文件不可访问。

    C语言的这种解决命名冲突的方案是可行的,不然不会有Linux内核这样大的项目,并且C++早期就是这样做的,但这种方法太生硬,没有从语言本身去解决问题,显得不够美观。

    1.3 命名空间如何解决问题

    为了实现命名空间机制,C++引入namespace关键字,定义命名空间的语法为:

    namespace xx
    {
    	...
    };
    

    命名空间本质上其实是对全局变量和函数在一定范围内链接属性的更改和控制,尖括号{}内就是命名空间的范围。一个特定名称的namespace,比如上面的xx,一对大括号内部定义的变量、函数、类等均属于该命名空间内。

    在命名空间内部互相引用时可以直接使用变量名、函数名等,跨命名空间互相引用时必须同时指定被引用方的命名空间名和变量名、函数名才可以找到,因此其实命名空间看起来就好像是给这个变量名、函数名添加了一种前缀。

    1.4 关于语言特性的思考

    语言特性是语言通过关键字或符号所支持、所引入的一种功能特性,如namespacetemplate运算符重载等。语言特性必定对应解决某种问题,必定在某方面对程序员有帮助,是有了某个问题不好解决才需要引入一种语言特性或者说机制来解决这个问题。

    语言特性越多或者设计越复杂,则语言本身就越难使用,但语言就越厉害,C++就是这样的一种语言。语言特性体现为某种语法,本质上靠编译工具链(预处理器、编译器、链接器等)提供支持,C++11/14/17/20的版本变迁,无非是新增或修正某些细节语言特性。就事论事讨论编程语言,其实难点都在掌握和熟练运用语言特性上。

    2.namespace的初级定义和使用

    2.1 同一文件内定义namespace

    #include<iostream>
    using namespace std;
    
    namespace test{
    int a;
    float b;
    void test_func(void){
    	cout<<"test_func"<<endl;
    }
    };
    

    2.2 同一文件内使用namespace

    namespace有三种引用方法。

    方式一:不做任何声明直接使用,类似于添加前缀,::叫做作用于解析符,左边是命名空间的名字,右边是该空间内的变量或函数名。这样编译器就会知道你要用的是test命名空间中的变量a以及函数test_func()

    int main(int argc,char**argv)
    {
    	test::a;
    	test::test_func();
    	return 0;
    }
    

    方式二:通过using告诉编译器去test空间中寻找test_func来使用。

    //声明test_func可以到test中找
    using test::test_func();
    
    //使用test_func
    int main(int argc,char**argv)
    {
    	test_func();
    	return 0;
    }
    

    方式三:直接声明命名空间,则该命名空间下的变量函数可以直接使用。

    using namespace test;
    
    int main(int argc,char**argv)
    {
    	test_func();
    	return 0;
    }
    

    2.3 不同cpp文件间定义和使用namespace

    在文件1中定义的变量和函数是可以在另一个文件2中被使用的,关键是如何在文件2中声明。规范的方法应该是同时写一个test1.hpp,即头文件,在头文件中写入命名空间以及命名空间内的函数声明,在.cpp文件中写函数的实现,然后在调用该函数的源文件中包含该头文件。

    test1.hpp:

    #ifndef TEST1_H
    #define TEST1_H
    
    namespace test1
    {
    	void func_1();
    };
    
    #endif
    

    test1.cpp

    #include"test1.hpp"
    #include<iostream>
    
    void test1::func_1()
    {
    	std::cout<<"this is test1 func1"<<std::endl;
    }
    

    test2.cpp

    #include"test1.hpp"
    
    using namespace test1;
    
    int main(int argc,char**argv)
    {
    	func_1();
    	return 0;
    }
    

    编译命令:

    g++ test2.cpp test1.cpp 
    
    展开全文
  • 目录命名空间的引入namespace的初级定义和使用1、同一文件内定义和使用命名空间2、不同C文件间定义和使用命名空间3、默认命名空间4、匿名命名空间的定义和使用5、嵌套命名空间的定义和使用 命名空间的引入 1、...


    命名空间的引入


    1、C语言如何解决名称冲突
    (1)大项目中会有很多C文件,项目中的全局变量和函数理应能互相访问,因此名称冲突是客观存在。
    (2)C中解决名称冲突的办法是:
    第一:同一个C文件不要太大,由一个人写;
    第二:每个C文件(或几个C文件构成的一个模块)中所有全局变量和函数前加统一的唯一前缀
    第三:不需要文件外访问的全局变量和函数前面都加static

    2、命名空间的引入
    (1)命名空间namespace,是C++引入的一种解决全局变量和函数名冲突的机制
    (2)C语言没有namespace,但是C++及之后的java, python等都有
    (3)namespace的关键点有2个:一是如何解决名称冲突,二是如何合法访问变量

    3、命名空间如何解决问题
    (1)为实现命名空间机制,C++引入了namespace关键字,定义格式为namespace xx{};
    (2)一个特定名称的namespace的一对大括号内部定义的变量、函数、类等均属于该命名空间内
    (3)在命名空间内部互相引用时可以直接使用变量名、函数名等
    (4)跨命名空间互相引用时必须同时指定被引用方的命名空间名和变量名函数名才可以找到
    (5)命名空间看起来就好像一种前缀
    (6)命名空间本质上其实是对全局变量和函数在一定范围内链接属性的更改和控制


    namespace的初级定义和使用


    1、同一文件内定义和使用命名空间

    (1)namespace的三种引用方法

    namespace NS1
    {
    	void func2(void)
    	{
    		
    	}
    	
    	void func1(void)
    	{
    		func2();
    	}
    
    };
    
    //using NS1::func1;			// 第二种访问方式
    //using namespace NS1;		// 第三种访问方式
    
    
    int main(void)
    {
    
    	NS1::func1();		// 第一种访问方法
    	func1();		
    	
    	return 0;
    }
    

    2、不同C文件间定义和使用命名空间

    在这里插入图片描述

    3、默认命名空间

    (1)又叫全局命名空间
    (2)其他命名空间引用默认命名空间中的方法::f();

    void func5(void);
    
    namespace NS1
    {
    	void func2(void)
    	{
    		::func5();			// 表示func5定义和声明在默认命名空间中
    	}
    	
    };
    
    
    int main(void)
    {
    	
    	func5();
    	
    	return 0;
    }
    
    
    void func5(void)
    {
    		
    }
    

    4、匿名命名空间的定义和使用

    std和cout的引入
    (1)std是C++标准库定义好的一个namespace
    (2)cout是std这个namespace下的一个标准输出工具,类似于C中的printf

    hello.cpp

    #include <iostream>
    
    using namespace std;
    
    namespace 
    {
    	extern void func2(void);    //声明了hello2.cpp中的匿名空间里面的函数
    }
    
    
    namespace NS
    {
    	void func1(void)
    	{
    		func2();    //有警告,连接时发生错误
    	}
    };
    
    
    
    int main(void)
    {
    	NS::func1();
    	
    	return 0;
    }
    

    hello2.cpp

    #include <iostream>
    
    using namespace std;
    
    namespace 
    {
    	void func2(void)
    	{
    		cout << "func2 from anonymous namespace" << endl;
    	}
    }
    
    

    在这里插入图片描述

    匿名命名空间的价值

    1. 匿名命名空间中的符号纯文件内部使用不需要被外部引用
    2. 匿名命名空间效果类似于全局变量和函数加static,但是比C中的static使用范围广
    3. 匿名命名空间的用法逻辑上符合整个命名空间的一贯原则

    5、嵌套命名空间的定义和使用

    #include <iostream>
    
    using namespace std;
    
    namespace NS1
    {
    
    	namespace NS2
    	{
    		void func1(void)
    		{
    			cout << "NS1::NS2::func1." << endl;
    		}
    		
    		void func2(void)
    		{
    			cout << "NS1::NS2::func2" << endl;	
    		}
    	}
    	
    	void func2(void)
    	{
    		cout << "NS1::func2." << endl;
    	}
    				
    }
    
    
    int main(void)
    {
    	NS1::NS2::func2();  //输出NS1::NS2::func2
    
    	NS1::func2();     //输出NS1::func2.
    
    	return 0;
    }
    
    
    展开全文
  • 目录:一、笔记二、笔记目录一、笔记① 定义函数的过程中,没有给定名称的函数就叫做匿名函数,Python中使用lambda表达式来创建匿名...3. lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空...
  • 匿名函数: 没有名字的函数/定义时未直接命名的函数。 优点: 非匿名函数在定义时,已经创建了函数对象和作用域...匿名函数如何使用: 将匿名函数赋值给一个变量,这样可以通过变量进行调用。匿名函数自调用 自
  • 1.声明 当前内容主要为学习和测试使用当前的C++中的类,并在类中定义匿名的结构,并访问和使用 ... * 当前内容主要为测试和使用C++中如何使用不完全的结构声明 * 1. 测试在不明确结构的定义的情况下编写代码 */ #i
  • 如何封装JS 库

    2009-11-13 09:19:42
    挑选一个独一无二的命名空间的名字(如Google Maps的G),注意js是大小写敏感的 不共享 为了不与著名的一些库或者其他已有的一些函数冲突,使用匿名函数。 [code="java"](function () { // 你要...
  • 讲解了JavaScript的函数、匿名函数、函数表达式、函数的递归调用、闭包等知识点,讲解了如何使用闭包来避免命名空间污染的问题,探讨了两个专题单例和回调
  • 应该考虑预计磁盘空间使用、存储管理、网络流量及其他与服务器基础结构有关的过程。 Active Directory:该用户隔离模式需要在 Windows Server 2003 家族中的操作系统上运行 Active Directory 服务器。Windows ...
  • 这一版能够支持对效果的更灵活定制,而且借助新增的命名空间事件,也使插件开发变得更容易。 jQuery UI(2007年9月):这个新的插件套件是作为曾经流行但已过时的Interface插件的替代项目而发布的。jQuery UI中包含...
  • 代码重定义

    2020-03-18 17:05:19
    使用匿名命名空间(拓展)4. 变量使用static关键字(拓展)三种链接属性(拓展)反思 引言     变量重定义,简而言之就是同一个变量名定义了两次或者多次。如下面的代码所示,在test.h中定义了一个字符串,但是我在...
  • 本文档将介绍如何使用 CSharp 驱动接口编写使用 SequoiaDB 数据库的程序,包括 SequoiaDB 数据库 CSharp 驱动的简单示例,详细的使用规范可参照官方的 CSharp API 文档。 命名空间 在使用 CSharp 驱动的相关 API ...
  • 6.3.7 在Web服务合约中如何使用类型 6.4 命名空间 6.4.1 目标命名空间 6.4.2 受限的与非受限的元素 6.4.3 命名空间与模式复用 6.5 消息结构 第7章 基本WSDL(一):抽象描述设计 7.1 WSDL定义和文档 7.1.1 ...
  • 6.3.7 在Web服务合约中如何使用类型 6.4 命名空间 6.4.1 目标命名空间 6.4.2 受限的与非受限的元素 6.4.3 命名空间与模式复用 6.5 消息结构 第7章 基本WSDL(一):抽象描述设计 7.1 WSDL定义和文档 7.1.1 ...
  • 1.如何避免js冲突 1.切忌全局变量泛滥,可以用匿名函数把脚本包起来。 比如: ...2.为了解决匿名函数之间的通信问题,我们...但是这种方法里,GLOBAL的属性很容易被不同的工程师覆盖,所以,我们可以使用命名空间
  • jquery轮播图插件

    2020-01-01 17:29:18
    3. 独立的空间:匿名函数 4. 严格模式:"use strict" 5.私有化$:给匿名函数传参,使用$接收,$变成了参数,也就是局部变量 二、如何将插件的功能绑定给jq 假设有一个对象myObj var myObj = { _qfshow:function(){ ...
  • C#2.0 特性

    2015-04-12 22:54:00
    命名空间别名限定符 静态类 外部程序程序集别名 属性访问器可访问性 委托中的协变和逆变 如何声明、实例化、使用委托 固定大小的缓冲区 友元程序集 内联警告控制 volatile 此版本的C#编辑器中引入下列增加...
  • 14.1.8 使用命名空间别名限定符(::) 280 14.2 预处理器 281 14.2.1 #define 281 14.2.2 #if和#endif 282 14.2.3 #else和#elif 284 14.2.4 #undef 287 14.2.5 #error 287 14.2.6 #warning 288 14.2.7 #line 289 ...
  • 轻松学C#(图解版)

    热门讨论 2014-04-27 19:50:54
    第三篇是应用技术篇,主要介绍的是异常处理、文件和流、委托、事件、Lambda表达式、命名空间、预处理器、程序集、运行时类型标识、反射、特性、泛型、LINQ和数据库开发等。 =======================================...
  • 1.3.3 如何使用MSDN帮助 11 1.3.4 利用MSDN帮助附带的示例学习编程 12 1.4 创建第一个C# 程序 13 1.4.1 创建项目 13 1.4.2 设计界面 14 1.4.3 编写代码 15 1.4.4 调试运行 16 1.4.5 保存项目 17 1.5...
  • 6.2安全命名空间配置入门 50 6.2.1 web.xml配置 50 6.2.2最小的配置 50 6.2.3表单和基本登录选项 52 设置默认的登录目的地 54 6.2.4注销处理 54 6.2.5使用其他身份验证提供程序 55 添加密码编码器 56 6.3高级Web功能...
  •  本书知识系统全面,拥有字典般的容量,可随用随查,涵盖指针、面向对象、操作符重载、流、命名空间、模板、异常处理、宏等主流c++开发技术。为了使读者能够活学活用,本书针对重要的概念精心设计了438个实用范例,...
  • 此外,《ASP.NET 4高级程序设计(第4版)》专门提供了两章的内容来教你如何用Ajax 技术制作快速响应的页面,以及如何使用微软的ASP.NETAJAX平台。另外,还专门介绍了ASP.NET4 新增的功能,如MVC 和动态数据等。  ...
  • 此外,《ASP.NET 4高级程序设计(第4版)》专门提供了两章的内容来教你如何用Ajax 技术制作快速响应的页面,以及如何使用微软的ASP.NETAJAX平台。另外,还专门介绍了ASP.NET4 新增的功能,如MVC 和动态数据等。  ...
  • 1.3 使用命名空间 12 1.4 创建图形应用程序 15 第1章快速参考 22 第2章 使用变量、操作符和表达式 25 2.1 理解语句 25 2.2 使用标识符 26 2.3 使用变量 27 2.3.1 命名变量 27 2.3.2 声明变量 28 2.4 使用...
  •  本书添加了许多新示例,来解释如何使用C#完成各种任务。另外,还增加了一些全新的章节,包括LINQ、SQL、ADO.NET实体、Windows Communication Foundation、Windows Workflow Foundation、Windows Presentation ...
  •  本书添加了许多新示例,来解释如何使用C#完成各种任务。另外,还增加了一些全新的章节,包括LINQ、SQL、ADO.NET实体、Windows Communication Foundation、Windows Workflow Foundation、Windows Presentation ...
  •  本书添加了许多新示例,来解释如何使用C#完成各种任务。另外,还增加了一些全新的章节,包括LINQ、SQL、ADO.NET实体、Windows Communication Foundation、Windows Workflow Foundation、Windows Presentation ...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 124
精华内容 49
关键字:

匿名命名空间如何使用