c++ namespace命名空间详解
What is a namespace?
A namespace defines an area of code in which all identifiers are guaranteed to be unique. By default, all variables and functions are defined in the global namespace. For example, take a look at the following snippet:
1
2
3
4
5
|
int nX = 5; int foo( int nX) { return -nX; } |
Both nX and foo() are defined in the global namespace.
Namespaces allow to group entities like classes, objects and functions under a name. This way the global scope can be divided in "sub-scopes", each one with its own name.
命名空间把对象,函数,变量等分组,然后有一个名字。
The format of namespaces is:
namespace identifier
{
entities
}
Where identifier is any valid identifier and entities is the set of classes, objects and functions that are included within the namespace. For example:
实体可以是任何有效的标识符。
namespace myNamespace
{
int a, b;
}
In this case, the variables a and b are normal variables declared within a namespace called myNamespace. In order to access these variables from outside the myNamespace namespace we have to use the scope operator ::. For example, to access the previous variables from outside myNamespace we can write:
|
|
The functionality of namespaces is especially useful in the case that there is a possibility that a global object or function uses the same identifier as another one, causing redefinition errors. For example:
// namespaces
#include <iostream>
using namespace std; namespace first
{
int var = ;
} namespace second
{
double var = 3.1416;
} int main () {
cout << first::var << endl;
cout << second::var << endl;
return ;
}
n this case, there are two global variables with the same name: var. One is defined within the namespace firstand the other one in second. No redefinition errors happen thanks to namespaces.
using
The keyword using is used to introduce a name from a namespace into the current declarative region. For example:
#include <iostream>
using namespace std; namespace first
{
int x = ;
int y = ;
} namespace second
{
double x = 3.1416;
double y = 2.7183;
} int main () {
using first::x;
using second::y;
cout << x << endl;
cout << y << endl;
cout << first::y << endl;
cout << second::x << endl;
return ;
}
5
2.7183
10
3.1416Notice how in this code, x (without any name qualifier) refers to first::x whereas y refers to second::y, exactly as our using declarations have specified. We still have access to first::y and second::x using their fully qualified names. The keyword using can also be used as a directive to introduce an entire namespace:using可以引入整个namespace。
// using
#include <iostream>
using namespace std; namespace first
{
int x = ;
int y = ;
} namespace second
{
double x = 3.1416;
double y = 2.7183;
} int main () {
using namespace first;
cout << x << endl;
cout << y << endl;
cout << second::x << endl;
cout << second::y << endl;
return ;
}
In this case, since we have declared that we were using namespace first, all direct uses of x and y without name qualifiers were referring to their declarations in namespace first.
using and using namespace have validity only in the same block in which they are stated or in the entire code if they are used directly in the global scope. For example, if we had the intention to first use the objects of one namespace and then those of another one,
using 和using namespace 仅仅在他们声明的代码块有效,如果在全局作用域中直接使用,则在整个代码块中有效。
we could do something like:
// using namespace example
#include <iostream>
using namespace std; namespace first
{
int x = ;
} namespace second
{
double x = 3.1416;
} int main () {
{
using namespace first;
cout << x << endl;
}
{2
using namespace second;
cout << x << endl;
}
return ;
}
5
3.1416
Namespace alias
We can declare alternate names for existing namespaces according to the following format: namespace new_name = current_name;命名空间里的变量冲突:
#include<iostream>
using namespace std;
int x=;
int y=;
namespace first
{
int var=;
int x=;
int y=;
}
namespace second
{
double var=3.1416;
double x=5.5;
double y=10.5;
}
int main()
{
using namespace first;
cout<<x<<endl;
x显示冲突
}
命名空间嵌套:
C++ does not allow compound names for namespaces.
// pluslang_namespace.cpp
// compile with: /c
// OK
namespace a {
namespace b {
int i;
}
} // not allowed
namespace c::d { // C2653
int i;
}
下面的代码嵌套命名空间;
#include<iostream>
using namespace std; namespace A
{
void fun1(){ cout<<"fun1"<<endl; } namespace B
{
int a=;
void fun1(){ cout<<"b fun1"<<endl;}
}
}
int main()
{
using namespace A;
fun1(); //print fun1
B::fun1(); //print b fun1
}
我们也可以用;
A::fun1();
A::B::fun1();
结果一样。(某个名字在自己的空间之外使用,在反复地在前面加上名字空间作为限定词)
无名名字空间,无名名字空间主要是保持代码的局部性,使用如下:
namespace
{
const int CVAR1 = 1;
void test();
}
由于该命名空间没有名字,不能被外部范围。(有什么用,我们可以
但一定要注意的一点是,在C++编译器实现时,无名名字空间其实是有名字的,这个隐含的名字跟它所在编译单元名字相关。所以基于这一点,我们不能跨编译单元使用无名名字空间中的名字。
上面的声明等价于
namespace $$$
{
const int CVAR1 = ;
void test();
}
using namespace $$$;
其中$$$在其所在的作用域里具有惟一性的名字,每个编译单元里的无名名字空间也是互不相同的,using namesapce $$$只是当前的编译单元的隐含名字,所以不能跨编译单元使用无名名字空间中的名字。
假设上面的test方法在是a.h与a.cpp中定义与实现的,但在b.h或b.cpp中就不能直接使用test方法或CVAR1。因为在b的这个编译单元中链接的是b这个编译单元中的test符号,并非a编译单元中的test符号,也就会出现未定符号。
要避免名字空间使用很短的名字,也不能太长,更不能嵌套太深了,个人觉得不要超过4层。
命名空间可以是不连续的
一个命名空间可以分散定义在多个文件中。不过,如果命名空间的一个部分需要使用一个定义在另一文件中的名字,必须声明该名字。
namespace namespace_name {
// declarations
}
如果namespace_name不是引用前面定义的命名空间,则用该名字创建新的命名空间,否则,这个定义打开一个已存在的命名空间,并将新声明加到那个命名空间。
接口和实现的分离
可以用分离的接口文件和实现文件构成命名空间。可以用与管理类和函数定义相同的方法来组织命名空间。定义多个不相关类型的命名空间应该使用分离的文件分别定义每个类型。
// sales_item.h
namespace cplusplus_primer {
class SalesItem { /* … */ };
SalesItem operator+(const SalesItem&, const SalesItem&);
} // query.h
namespace cplusplus_primer {
class Query {
public:
Query(const std::string&);
std::ostream & display(std::ostream&) const;
};
} // sales_item.cpp
#include “sales_item.h”
namespace cplusplus_primer {
// definitions for SalesItem members and overloaded operators
} // query.cpp
#include “query.h”
namespace cplusplus_primer {
// definitions for Query members and related functions
}
示例:
namespace C //命名空间不连续1.h
{
class A
{
private:
int a,b;
public:
void func();
};
}
#include"命名空间不连续1.h"
#include<iostream>
using namespace std;
namespace C
{
void A::func()
{
a=,b=;
cout<<a<<b<<endl;
cout<<"fun1"<<endl;
}
} int main()
{
using namespace C;
A a;
a.func();
}
定义命名空间成员
可以在命名空间定义的外部定义命名空间成员,类似于在类外部定义类成员的方式。
// namespace members defined outside the namespace must use qualified names
cplusplus_primer::operator+(const SalesItem&, const SalesItem&)
{
SalesItem ret(lhs);
// …
}
c++ namespace命名空间详解的更多相关文章
- linux命名空间详解_转
转自: Linux的命名空间详解--Linux进程的管理与调度(二) Linux Namespaces机制提供一种资源隔离方案. PID,IPC,Network等系统资源不再是全局性的,而是属于特定的 ...
- C++命名空间详解
使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突.在C++中,变量.函数和类都是大量存在的.如果没有命名空间,这些变量.函数.类的名称将都存在于全局命名空间中,会导致很多冲突.比如,如果我 ...
- C#命名空间详解namespace
命名空间是一个域,这在个域中所有的类型名字必须是唯一的,不同的类型分组归入到层次化的命名空间, 命名空间的好处是:1.避免名字冲突,2.便于查找类型名字. 如:System.secruity.Cry ...
- [转载]C++之using namespace std 详解与命名空间的使用
来源:https://blog.csdn.net/Bruce_0712/article/details/72824668 所谓namespace,是指标识符的各种可见范围.C++标准程序库中的所有标识 ...
- django 命名空间详解
include(module[, namespace=None, app_name=None ]) include(pattern_list) include((pattern_list, app_n ...
- Linux的命名空间详解--Linux进程的管理与调度(二)【转】
Linux Namespaces机制提供一种资源隔离方案. PID,IPC,Network等系统资源不再是全局性的,而是属于特定的Namespace.每个Namespace里面的资源对其他Namesp ...
- Linux的命名空间详解--Linux进程的管理与调度(二)
转自:http://blog.csdn.net/gatieme/article/details/51383322 日期 内核版本 架构 作者 GitHub CSDN 2016-05-12 Linux- ...
- c++的重载 缺省参数和命名空间详解
参加了几次笔试,发现有很多c++方面的问题被卡了.从现在开始进攻c++.之后会陆续更新c++学习笔记. 先说说我学习的书籍,大家如果有好的书籍推荐,感谢留言. 暂时是在看这些书自学. 1.C++介绍. ...
- Thinkphp5.0实战开发一------命名空间详解
序言 ThinkPHP是一个快速.兼容而且简单的轻量级国产PHP开发框架,使用ThinkPHP框架可以极大简化我们的开发过程,节省时间.这个专题我将记录自己学习使用ThinkPHP5.0的进行实战开发 ...
随机推荐
- $.ajax和vue-resource实现OAuth
Vue.js——使用$.ajax和vue-resource实现OAuth的注册.登录.注销和API调用 概述 上一篇我们介绍了如何使用vue resource处理HTTP请求,结合服务端的REST A ...
- Jass 技能模型定义(转)
Jass是什么? 先阐释一下什么是jass吧,百度:JASS(正确地说是JASS 2)是魔兽3的程序语言,用于控制游戏和地图的进行,也是魔兽游戏和地图的基础. 地图编辑器中摆放的单位(Un ...
- Trie三兄弟——标准Trie、压缩Trie、后缀Trie
1.Trie导引 Trie树是一种基于树的数据结构,又称单词查找树.前缀树,字典树,是一种哈希树的变种.应用于字符串的统计与排序,经常被搜索引擎系统用于文本词频统计.用于存储字符串以便支持快速模式匹配 ...
- ThinkPHP 3.1.2 视图-2
一.模板的使用 (重点) a.规则 模板文件夹下[TPL]/[分组文件夹/][模板主题文件夹/]和模块名同名的文件夹[Index]/和方法名同名的文件[index].html(.tpl) 更换模板文件 ...
- 宣布发布 Windows Azure ExpressRoute,宣告与 Level 3 建立全新的合作伙伴关系并推出关于其他 Azure 服务令人振奋的更新
在我们与世界各地的客户和合作伙伴交谈时,总会听到他们说,希望找到一个提供商帮助他们最大限度地发挥内部部署投资的作用并且能够利用云的灵活性.这是我们构建混合云策略和云操作系统愿景的基本原则.本着我 ...
- HDU 2067 小兔的棋盘
题解:卡特兰数的几何意义,所以答案就是卡特兰数的两倍 #include <cstdio> #include <iostream> using namespace std; #d ...
- Python学习入门基础教程(learning Python)--2.2 Python下的变量基础
变量的基本概念,变量可以这样去理解,变量是一个值,这个值存储在计算机的内存里.以网购为例,您在选购傻商品的时候,是在不同页面里选不同的商品,选好一件点击“放入购物车”,选完了再点击去结帐,这些商品的价 ...
- MongoDB初探系列之二:认识MongoDB提供的一些经常使用工具
在初探一中,我们已经能够顺利的将MongoDB在我们自己的机器上跑起来了. 可是在其bin文件夹以下另一些我们不熟知的工具.接下来,将介绍一下各个小工具的用途以及初探一中MongoDB在data文件夹 ...
- HDU 3032 Nim or not Nim? (sg函数求解)
Nim or not Nim? Problem Description Nim is a two-player mathematic game of strategy in which players ...
- 【企业库6】【日志应用程序块】实验2:创建和使用异步Trace Listener
Lab 2: Create and Use an Asynchronous Trace Listener 实验2:创建和使用异步Trace Listener In this lab, you will ...