命名空间是为了防止名字(符号)冲突而把一系列的类型、变量、函数放在一起的一种方式,命名控件要和变量作用域放在一起来理解,在作用域范围内使用命名空间就可以访问该命名空间内定义的符号。命名空间用如下的方式定义:
namespace System
{
// 符号定义,类型、变量、函数等
};
和类、结构类似,但不能实例化,只可以引用。
namespace System
{
// 符号定义,类型、变量、函数等
};
和类、结构类似,但不能实例化,只可以引用。
解决方案 »
- 小鸟开始找工作 散分纪念
- opengl绘制二次曲线
- CComboBox 控件,响应ON_CBN_SELCHANGE消息时为何鼠标光标不显示?
- 关于服务器内存释放的问题
- 用DirectShow时的编译错误!!!
- 如何取得中文字符的拼音首字母
- 如何将自己写的Windows服务在 "我的电脑"->"管理"->"服务和应用程序" 下面显示?
- 回答别人贴子,别人已经给了我50分,为什么我的分数还是没变(20分)呀?
- 请问VFW可以实现MPEG1的数据流进行实时播放吗?请问在哪里可以找到相关资料?
- MFC 读Excel很慢怎么办
- 坐标变换~~~双缓存~~~~~~~高分!!!
- LINK : warning LNK4098: defaultlib "MSVCRT" conflicts with use of other libs; use /NODEFAULTLIB:library
为了防止命名冲突,
可以保证,在某个名字空间里的命名对象不会产生冲突
STd就是这样的,
你可以定义自己的名字空间,
namespace myspace
{
class A
{
}
class B
....
struct
....
....
}外人使用时相当与这么用myspace::A
不会冲突了吧,前面有个限定(用哪个空间下的...,myspace::)
char func(char);
class String { ... };// somelib.h
class String { ... };如果按照上述方式定义,那么这两个头文件不可能包含在同一个程序中,因为String类会发生冲突。
所谓命名空间,是一种将程序库名称封装起来的方法,它就像在各个程序库中立起一道道围墙。比如:
// one.h
namespace one
{
char func(char);
class String { ... };
}// somelib.h
namespace SomeLib
{
class String { ... };
}现在就算在同一个程序中使用String类也不会发生冲突了,因为他们分别变成了:one::String()以及Somelib::String()这样,就可以通过声明命名空间来区分不同的类或函数等了。
比如C++标准库定义了命名空间:std,其中包含容器vector,示例如下:
#include "stdafx.h"
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;int main(int argc, char* argv[])
{
const int arraysize = 7;
int ia[arraysize] = {0,1,2,3,4,5}; file://定义容器vector
vector<int> ivect(ia,ia+arraysize); vector<int>::iterator it1 = find(ivect.begin (),ivect.end (),4);
if(it1 == ivect.end ())
cout<<"4 not found "<<endl;
else
cout<<"4 found "<<*it1<<endl; return 0;
}输出结果为:4 found 4.
1)作用域与命名空间<!--[if !supportLists]-->l <!--[endif]-->相关概念与命名空间相关的概念有:<!--[if !supportLists]-->n <!--[endif]-->声明域(declaration region)—— 声明标识符的区域。如在函数外面声明的全局变量,它的声明域为声明所在的文件。在函数内声明的局部变量,它的声明域为声明所在的代码块(例如整个函数体或整个复合语句)。<!--[if !supportLists]-->n <!--[endif]-->潜在作用域(potential scope)—— 从声明点开始,到声明域的末尾的区域。因为C++采用的是先声明后使用的原则,所以在声明点之前的声明域中,标识符是不能用的。即,标识符的潜在作用域,一般会小于其声明域。<!--[if !supportLists]-->n <!--[endif]-->作用域(scope)—— 标识符对程序可见的范围。标识符在其潜在作用域内,并非在任何地方都是可见的。例如,局部变量可以屏蔽全局变量、嵌套层次中的内层变量可以屏蔽外层变量,从而被屏蔽的全局或外层变量在其倍屏蔽的区域内是不可见的。所以,一个标识符的作用域可能小于其潜在作用域。 <!--[if !supportLists]-->l <!--[endif]-->命名空间命名空间(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.hnamespace 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 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<String> vs[5];List<int> li[10];my_f(vs[2], li[5]);
3)使用命名空间<!--[if !supportLists]-->l <!--[endif]-->作用域解析运算符(::)对命名空间中成员的引用,需要使用命名空间的作用域解析运算符::。例如:// out1.cpp#include "out.h"#include <iostream>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::endl; std::cout << "Outer::i = " << Outer::i << ", Inner::i = " << Outer::Inner::i << std::endl;}
int A::B::func()
{
return 1;
}上面这个函数定义中的A和B既可以是命名空间,也能是类名,它能是多种申明方式:
申明一:
namespace A
{
namespace B
{
int func();
};
};申明二:
namespace A
{
class B
{
int func();
};
};申明三:
class A
{
class B
{
int func();
};
};但两者其实还有很大的区别:
1、命名空间里面可以嵌套命名空间或者类,但类里面不能嵌套定义命名空间,只能嵌套定义类。
2、类名是一种命名空间,但更多的作用是限定作用域;命名空间并不限定作用域,它只是一种符号名称的扩展(如楼上各位所述解决命名冲突)。