命名空间详解namespace,namespace命名空间

C++ namespace命名空间详细解释,namespace命名空间

命名空间

在C++中,名称(name)能够是符号常量、变量、宏、函数、结构、枚举、类和目的等等。为了制止,在普遍程序的宏图中,以至在程序员使用各式各样的C++库时,那个标志符的命名发生冲突,规范C++引进了首要字namespace(命名空间/名字空间/名称空间/名域),能够越来越好地调节标记符的功效域。

MFC中并不曾利用命名空间,不过在.NET框架、MC++和C++/CLI中,都大方运用了命名空间。

1)效率域与命名空间

l相关概念

与命名空间相关的概念有:

n评释域(declaration
region)——证明标记符的区域。如在函数外面注明的全局变量,它的注脚域为注解所在的文本。在函数内注脚的有的变量,它的申明域为申明所在的代码块(举个例子整个函数体或任何复合语句)。

n潜在效用域(potential
scope)——从阐明点领头,到声明域的结尾的区域。因为C++选拔的是先申明后选拔的条件,所以在注解点早先的评释域中,标记符是不能够用的。即,标记符的机密功效域,平日会低于其注解域。

n功用域(scope)——标记符对程序可以看到的限制。标识符在其地下效果域内,并非在别的省方都以可以知道的。举个例子,局地变量能够屏蔽全局变量、嵌套档案的次序中的内层变量能够遮挡外层变量,进而被屏蔽的大局或外层变量在其倍屏蔽的区域内是不可以预知的。所以,叁个标志符的功能域大概低于其潜在功效域。

l命名空间

取名空间(namespace)是生机勃勃种描述逻辑分组的编写制定,能够将按某个标准在逻辑上归于同三个公司的宣示放在同三个命名空间中。

原本C++标记符的功能域分成三级:代码块({……},如复合语句和函数体)、类和大局。以往,在其间的类和全局之间,规范C++又增加了命名空间那四个效用域等级。

取名空间能够是全局的,也足以献身另多个命名空间之中,可是不能够放在类和代码块中。所以,在命名空间中表明的称谓(标志符),暗中同意具有外界链接性子(除非它援引了常量)。

在具有命名空间之外,还存在一个大局命名空间,它对应于文件级的申明域。因此,在命名空间机制中,原本的全局变量,今后被以为位于全局命名空间中。

正式C++库(不包含专门的学问C库)中所富含的有所内容(蕴含常量、变量、结构、类和函数等)都被定义在命名空间std(standard标准)中了。

2)定义命名空间

有二种格局的命名空间——盛名的和无名氏的。

取名空间的定义格式为:(取自C++标准文书档案)

named-namespace-definition:

namespace identifier { namespace-body }

unnamed-namespace-definition:

namespace { namespace-body }

namespace-body:

declaration-seqopt

即:(本人翻译并改写的)

知名的命名空间:

namespace命名空间名{

注脚种类可选

}

无名的命名空间:

namespace {

扬言连串可选

}

取名空间的分子,是在命名空间定义中的花括号内声明了的名号。能够在命名空间的概念内,定义命名空间的分子(内部定义)。也得以只在命名空间的概念内注脚成员,而在命名空间的定义之外,定义命名空间的分子(外界定义)。

命名空间成员的外界定义的格式为:

取名空间名::成员名……

例如:

// out.h

namespace Outer { //命名空间Outer的定义

int i; //命名空间Outer的成员i的里边定义

namespace Inner { //子命名空间Inner的此中定义

void f() { i++; } //命名空间Inner的成员f()的此中定义,当中的i为Outer::i

int i;

void g() { i++; } //命名空间Inner的成员g()的中间定义,在那之中的i为Inner::i

命名空间详解namespace,namespace命名空间。void h(); //命名空间Inner的成员h()的声明

}

void f(); //命名空间Outer的成员f()的注解

//namespace Inner2; //错误,无法注解子命名空间

}

void Outer::f() {i–;} //命名空间Outer的成员f()的外界定义

void Outer::Inner::h() {i–;} //命名空间Inner的成员h()的表面定义

//namespace Outer::Inner2 {/*……*/} //错误,不能够在表面定义子命名空间

注意:

不能在命名空间的概念中注脚(另三个嵌套的)子命名空间,只好在命名空间的概念中定义子命名空间。

也不能够一向运用“命名空间名::成员名……”定义形式,为命名空间增添新成员,而必需先在命名空间的定义中加多新成员的宣示。

除此以外,命名空间是开放的,就可以以随即把新的成员名称参加到已有个别命名空间之中去。方法是,数次声称和定义同一命名空间,每回增多本身的新成员和称号。比方:

namespace A {

int i;

void f();

} //现在A有成员i和f()

namespace A {

int j;

void g();

} //现在A有成员i、f()、j和g()

还足以用多样办法,来组成现成的命名空间,让它们为笔者所用。比方:

namespace My_lib {

using namespace His_string;

using namespace Her_vector;

using Your_list::List;

void my_f(String &, List &);

}

……

using namespace My_lib;

……

Vector vs[5];

List li[10];

my_f(vs[2], li[5]);

3)使用命名空间

l效率域分析运算符(::)

对命名空间中成员的引用,须求动用命名空间的效应域深入分析运算符::。举个例子:

// out1.cpp

#include “out.h”

#include

int main ( ) {

Outer::i = 0;

Outer::f(); // Outer::i = -1;

Outer::Inner::f(); // Outer::i = 0;

Outer::Inner::i = 0;

Outer::Inner::g(); // Inner::i = 1;

Outer::Inner::h(); // Inner::i = 0;

std::cout << “Hello, World!” <

std::cout << “Outer::i = ” << Outer::i << “,Inner::i =
” << Outer::Inner::i << std::endl;

}

lusing指令(using namespace)

为了节约每一遍调用Inner成员和规范库的函数和对象时,都要增添Outer::Inner::和sta::的劳碌,能够利用标准C++的using编写翻译指令来简化对命名空间中的名称的接受。格式为:

using namespace命名空间名[::命名空间名……];

在这里条语句之后,就能够直接动用该命名空间中的标志符,而不要写前边的命名空间一定部分。因为using指令,使所钦点的满贯命名空间中的全体成员都间接可用。举个例子:

// out2.cpp

#include “out.h”

#include

//using namespace Outer; //编写翻译错误,因为变量i和函数f()知名称冲突

usingnamespace Outer::Inner;

usingnamespace std;

int main ( ) {

Outer::i = 0;

Outer::f(); // Outer::i = -1;

f(); // Inner::f(),Outer::i = 0;

i = 0; // Inner::i

g(); // Inner::g(),Inner::i = 1;

h(); // Inner::h(),Inner::i = 0;

cout << “Hello, World!” << endl;

cout << “Outer::i = ” << Outer::i << “,Inner::i = ”
<< i << endl;

}

又例如:(.NET框架)

using namespace System::Drawing::Imaging;

using namespace System::Window::Forms::Design::Behavior;

lusing声明(using)

除此而外能够使用using编译指令(组合关键字using
namespace)外,还足以应用using评释来简化对命名空间中的名称的利用。格式为:

using命名空间名::[取名空间名::……]成员名;

在乎,关键字using前边并未跟关键字namespace,并且最后必得为命名空间的分子名(而在using编写翻译指令的最后,必得为命名空间名)。

与using指令分化的是,using证明只是把命名空间的一定成员的称谓,加多该证明所在的区域中,使得该成员能够无需利用,(多级)命名空间的效用域拆解深入分析运算符来定位,而直白被接受。但是该命名空间的别样成员,依旧供给成效域解析运算符来定位。举个例子:

// out3.cpp

#include “out.h”

#include

using namespaceOuter; //注意,此处无::Inner

using namespace std;

// usingInner::f; //编写翻译错误,因为函数f()出名称冲突

usingInner::g;
//此处省去Outer::,是因为Outer已经被眼下的using指令作用过了

usingInner::h;

int main ( ) {

i = 0; // Outer::i

f(); // Outer::f(),Outer::i = -1;

Inner::f(); // Outer::i = 0;

Inner::i = 0;

g(); // Inner::g(),Inner::i = 1;

h(); // Inner::h(),Inner::i = 0;

cout << “Hello, World!” << endl;

cout << “Outer::i = ” << i << “,Inner::i = ” <<
Inner::i << endl;

}

lusing指令与using评释的可比

足见,using编写翻译指令和using表明,都得以简化对命名空间中名称的拜望。

using指令使用后,能够一劳永逸,对全部命名空间的具备成员皆有效,特别便利。而using注脚,则必需对命名空间的分裂成员名称,一个叁个地去声明,特别辛勤。

唯独,平时的话,使用using注解会更安全。因为,using注脚只导入钦定的名目,假使该名称与一些名称爆发冲突,编写翻译器会报错。而using指令导入整个命名空间中的全体成员的称号,包含那二个恐怕平素用不到的称呼,借使中间闻名称与一些名称产生冲突,则编写翻译器并不会产生任何警报新闻,而只是用部分名去自动覆盖命名空间中的同名成员。特别是命名空间的开放性,使得叁个命名空间的成员,或者分流在两个地方,技师难以规范明白,别人到底为该命名空间增加了什么称谓。

即便如此接收命名空间的章程,有五种可供选取。不过不能够贪图方便,生龙活虎味接受using指令,这样就全盘背离了规划命名空间的初志,也失去了命名空间应该具有的防御名称冲突的功力。

平常情状下,对有的时候使用的命名空间成员,应该使用命名空间的功效域深入分析运算符来直接给名称定位。而对多个大命名空间中的经常要动用的少数多少个成员,提倡使用using证明,而不应有选用using编写翻译指令。唯有必要频仍使用同四个命名空间的许繁多分羊时,使用using编写翻译指令,才被感到是亮点的。

例如,假若四个顺序(如上面包车型大巴outi.cpp)只使用意气风发一次cout,何况也不行使std命名空间中的别的成员,则足以选用命名空间的成效域拆解深入分析运算符来直接固定。如:

#include

……

std::cout << “Hello, World!” <

std::cout << “Outer::i = ” << Outer::i << “,Inner::i =
” << Outer::Inner::i <

又比如说,如果八个前后相继要反复使用std命名空间中的cin、cout和cerr(如上边的outi.cpp),而略带使用其余std命名空间中的其余成员,则应当利用using申明实际不是using指令。如:

#include

……

using std::cout;

cout<< “Hello, World!” <

cout<< “Outer::i = ” << Outer::i << “,Inner::i = ”
<< Outer::Inner::i <

4)命名空间的名目

l命名空间小名

正式C++引入命名空间,首借使为着防止成员的称号冲突。若果客商都给自身的命名空间取简短的称呼,那么这个(往往同是全局级的)命名空间自个儿,也说不许发生名称矛盾。假使为了防止冲突,而为命名空间取不长的名目,则利用起来就能不方便人民群众。那是二个独立的难堪难题。

正式C++为此提供了黄金时代种缓慢解决方案——命名空间小名,格式为:

namespace别名=命名空间名;

举个例子:(AT&T美利坚合众国电话电报公司)

namespace American_Telephone_and_Telegraph { //命名空间名太长

class String {

String(const char*);

//……

}

}

American_Telephone_and_Telegraph::String s1 //使用不方便人民群众

= new American_Telephone_and_Telegraph::String(“Grieg”);

namespace ATT = American_Telephone_and_Telegraph; //定义别称

ATT::String s2 = new ATT::String(“Bush”); //使用方便

ATT::String s3 = new ATT::String(“Nielsen”);

l无名氏命名空间

正式C++引进命名空间,除了可避防止成员的名号发生矛盾之外,还足以使代码保持局地性,进而爱抚代码不被别人违法利用。要是你的指标关键是后世,何况又为替命名空间取二个称心、有意义、且与别人的命名空间不重名的名目而烦闷的话,标准C++还允许你定义叁个无名鼠辈命名空间。你能够在现阶段编写翻译单元中(无名氏命名空间之外),直接动用匿名命名空间中的成员名称,可是在当前编写翻译单元之外,它又是不可以知道的。

无名氏命名空间的定义格式为:

namespace {

扬言体系可选

}

实质上,上边的定义等价于:(规范C++中有三个满含的选择指令)

namespace $$$ {

评释系列可选

}

using namespace $$$;

例如:

namespace {

int i;

void f() {/*……*/}

}

int main() {

i = 0; //可直接使用无名命名空间中的成员i

f(); //可直接运用无名命名空间中的成员f()

}

namespace命名空间安详严整,namespace命名空间
命名空间
在C++中,名称(name)可以是符号常量、变量、宏、函数、结构、枚举、类和对象等等。为…

   命名空间是多个域,那在个域中存有的项目名字必得是天下无敌的,差别的品种分组归入到档案的次序化的命名空间,

在此边中大家介绍了php教程命名空间的用场和namespace关键字,在这里篇小说中大家将介绍一下use命令的施用以至php如何解析命名空间的名字的。

命名空间的平价是:1、制止名字冲突,2、便于找寻类型名字。

namespace bakbaba;
function bab(){
    echo “bi”;
}
namespace kkk;
function k1(){
    echo “k1”;
}

如:System.secruity.Cryptogtaphy.

bakbababab();//在kkk的命名空间下利用其余命名空间,注意前方的
use bakbaba as
b;//如故在kkk的命名空间下,可是用外号的的时候以下措施也不利
#use bakbaba as b;//前边能够不使用号
bbab();//使用小名下命名空间的时候前边不应当有号
k1();//调用该函数没有报错,表明use不影响当下当前定名空间

下边介绍namespace 关键字的利用。

 

namespace test

< ?php  
// application library 1  
namespace applib1;  
const myconst = ‘applib1myconst’;  
function myfunction() {  
 return __function__;  
}  
class myclass {  
 static function whoami() {  
eturn __method__;  
 }  
}  
?>
 

lib2.php
< ?php  
// application library 2  
namespace applib2;  
 
const myconst = ‘applib2myconst’;  
 
function myfunction() {  
 return __function__;  
}  
 
class myclass {  
 static function whoami() {  
eturn __method__;  
 }  
}  
?> 

{

幸亏在手册中发觉那样风流罗曼蒂克段代码,故手册中此外关于namespace的源委,就足以忽略了,直接看上面包车型客车代码

  class class0

 

  {

<?php
namespace a;
use bd, ce as f;

// 函数调用

foo();      // 首先尝试调用定义在命名空间”a”中的函数foo()
            // 再尝试调用全局函数 “foo”

foo();     // 调用全局空间函数 “foo”

myfoo();   // 调用定义在命名空间”amy”中等学校函授数 “foo”

f();        // 首先尝试调用定义在命名空间”a”中的函数 “f”
            // 再品尝调用全局函数 “f”

// 类引用

new b();    // 创制命名空间 “a” 中定义的类 “b” 的叁个目的
            // 如若未找到,则尝试自动装载类 “ab”

new d();    // 使用导入准则,创立命名空间 “b” 中定义的类 “d”
的叁个目的
            // 要是未找到,则尝试自动装载类 “bd”

new f();    // 使用导入法则,创设命名空间 “c” 中定义的类 “e”
的叁个指标
            // 若是未找到,则尝试自动装载类 “ce”

new b();   // 创制定义在大局空间中的类 “b” 的二个对象
            // 若是未开掘,则尝试自动装载类 “b”

new d();   // 创制定义在大局空间中的类 “d” 的三个指标
            // 假诺未发掘,则尝试自动装载类 “d”

new f();   // 创制订义在大局空间中的类 “f” 的一个对象
            // 假设未发现,则尝试自动装载类 “f”

// 调用另四个命名空间中的静态方法或命名空间函数

bfoo();    // 调用命名空间 “ab” 中等高校函授数 “foo”

b::foo();   // 调用命名空间 “a” 中定义的类 “b” 的 “foo” 方法
            // 要是未找到类 “ab” ,则尝试自动装载类 “ab”

d::foo();   // 使用导入准绳,调用命名空间 “b” 中定义的类 “d” 的 “foo”
方法
            // 如若类 “bd” 未找到,则尝试自动装载类 “bd”

bfoo();   // 调用命名空间 “b” 中的函数 “foo”

b::foo();  // 调用全局空间中的类 “b” 的 “foo” 方法
            // 即便类 “b” 未找到,则尝试自动装载类 “b”

// 当前命名空间中的静态方法或函数

ab::foo();   // 调用命名空间 “aa” 中定义的类 “b” 的 “foo” 方法
              // 若是类 “aab” 未找到,则尝试自动装载类 “aab”

ab::foo();  // 调用命名空间 “ab” 中定义的类 “b” 的 “foo” 方法
              // 假诺类 “ab” 未找到,则尝试自动装载类 “ab”
?>

    int i;

    public class0()

    {

    }
  }
}

using关键字选取

  ,访谈一个命名空间的剧情能够透过一丝一毫约束名。如:test.class0来拜望。不过每趟这样在程序写很麻烦。你能够行使using指令来援引类型。

命名空间的都以援引类型的。所以在前后相继的开始你能够先引用命名空间。有如你接纳VS编写翻译软件时,各样系统生成的Console中都有

using system;

using system.drawing;

using system.threading ;

今后就足以很方面选拔你援用命名空间的档案的次序了。注意using的利用,前边的还要对此做牵线。

大局命名空间

  大局命名空间有两片段构成:

  1、全体的甲级命名空间;

  2、全数未有在任何命名空间中声称的品类;

比如说:前边的例证的大局命名空间中注脚了test类型(归于第后生可畏种情景。卡塔 尔(英语:State of Qatar)

 比方:class outer{}//归于第二种状态;

  namespace test1{}是全局命名。

命名空间的规规矩矩

  名字功效域

  全体现身的外表命名空间中的名字都隐式地被引进到里头的命名空间中。在此个例子中middle
和class1被隐式的引进到inner中;

  namespace Outer

{

    namespace Middle

{

    class Class1{}

    namespace inner

{

    class class2:class1{}
}
}
}

在此个事例中:如下:

namespace test{
  namespace Common{

    class  class1{}
    }

  namespace Managerreporting{

    class class2:Common.class1{}
  }

}

能够看来三个test命名空间中带有八个不交的命名空间。要想援用其余三个,必需运用部分限制名。你能够旁观他和上边的例证的区分吧?

名字屏蔽

  内部命名空中的名字会掩没外界空间相仿的名字。

  例如;namespace Outer{
      namespace Middle{

        class class1{}

        class class2{}

相关文章