今天看到O(1)哥在看C++的课件,里面有一段代码是解释命名空间namespace的,PPT上面的代码编译不过,
由于第一次接触C++的namespace,不明白其中的奥妙,于是google之,看了网上的解析之后明白了许多,回过头来看程序,
才发现原来是类里面的函数f()没有具体实现,怪不得不能定位。具体代码如下:
#include <stdio.h>
namespace NameSpace1
{
class MyClass
{
public:
void f()
{
m = 1;
printf("%d\n", m);
}
private:
int m;
};
}
namespace NameSpace2
{
class MyClass
{
public:
void f()
{
m = 2;
printf("%d\n", m);
}
private:
int m;
};
}
int main()
{
NameSpace1::MyClass x;
x.f();
NameSpace2::MyClass y;
y.f();
return 0;
}
下面给出的namespace的用法(转载的,由于网络上转载太多,不知道谁是原作者了):
Namespaces
名字空间允许像类,对象和函数一样的一组实体归属于一个名称。把一个全局的范围化分成许多子的范围,每一个小的范围都有它自己的名字。
名字空间的格式是:
namespace identifier{
entities
}
包含在名字空间下的任何类,对象和函数中设立的实体必须是有效的标签符,例如:
namespace myNamespace{
int a, b;
}
这种情况,在被调用的名字空间myNamespace内部变量a和变量b被定义成了一个普通的变量,为了从myNamespace外部访问这些变量,我们必须使用作用域操作符::,例如,从myNamespace外部访问前面定义的变量,我们要这样写:
general::a
general::b
名字空间的功能一个全局的对象或者函数像另外一个对象一样使用了同一个标识符时特别有用,会引起重定义的错误,例如:
//namespace
#include <iostream>
using namespace std;
namespace first{
int var = 5;
}
namespace second{
double var = 3.1416;
}
int main() {
cout << first::var << endl;
cout << second::var <<endl;
return 0;
}
程序运行如下:
5
3.1416
这种情况我们使用了两个相同名字的全局变量:var。一个是被定义在first名字空间里的,另一个是被定义在second名字空间内的。因为有了名字空间所以没有发生重定义的错误。
using
使用using 这个关键字是为了将一个来到名字空间内的名字介绍到当前声明的区域,例如:
//namespace
#include <iostream>
using namespace std;
namespace first{
int x = 5;
int y = 10;
}
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 0;
}
程序运行如下:
5
2.7183
10
3.1416
如何注意这段代码,x(没有任何名字空间标识符)是引用first::x,而y引用second::y,正是由于我们在前面指定了using这个声明,所以们仍然要使用标识符全名来访问first::y 和 second::x。
关键字using也能直接指向一个实体名字空间。
//namespace
#include <iostream>
using namespace std;
namespace first{
int x = 5;
int y = 10;
}
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 0;
}
程序运行如下:
5
10
3.1416
2.7183
这个情况,我们定义过using namespace frist,所有直接使用x和y没有使用名字空间标识符而是引用了定义的名字空间frist。
using和using namespace 仅仅是在同一个块里有效,它们规定在整个代码内,是否是在全局范围里直接使用,例如,如果我们打算首先使用一个名字空间的对象,再使用别外一个名字空间的对象,我们应该这样做:
//namespace
#include <iostream>
using namespace std;
namespace first{
int x = 5;
}
namespace second{
double x = 3.1416;
}
int main() {
using namespace first;{
cout << x << endl;
}{
using namespace second;
cout << x <<endl;
}
return 0;
}
程序运行如下:
5
3.1416
名字空间别名(Namespace alias)
我们能改变一个已经存在的名字空间的命名,相应的格式如下:
namespace new_name = current_name;
名字空间std (namespace std)
C++标准类库中的所有实体都定义在名字空间std中,这就是为什么我们通常需要包含一个using namespace std,描述在所有的程序中使用的实体都定义在iostream中。