反反复复
分类: C/C++
2013-03-30 16:00:28
命名空间std,using namespace std
在标准C++以前,都是用#include
并不是写了#include
#include "iostream" 与 #include
后缀为.h的头文件c++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,c++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。
因此,当使用
#include
using namespace std; 则出错
所以 要么写成
#include
using namespace std;
要么写成
#include
当然最好是前种
例如:
在x.h中的内容为
// x.h
namespace MyNamespace1
{
class MyClass
{
public:
void f();
private:
int m;
}
};
在y.h中的内容为
// y.h
namespace MyNamespace2
{
class MyClass
{
public:
void f();
private:
int m;
}
};
然后在z.cpp中引入x.h和y.h
// z.cpp
#include "x.h"
#include "y.h"
void z::f()
{
//声明一个文件x.h中类MyClass的实例x
MyNamespace1::MyClass x;
//声明一个文件x.h中类MyClass的实例x
MyNamespace2::MyClass y;
//调用文件x.h中的函数f
x.f();
//调用文件y.h中的函数f
y.f();
}
名字空间实质上是一个作用域。
通过上面的一个实例应该知道名字空间的作用了吧。所谓namespace,是指标识符的各种可见范围。
C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
由于namespace的概念,使用C++标准程序库的任何标识符时,可以有三种选择:
1、直接指定标识符。例如std::ostream而不是ostream。完整语句如下:
std::cout << std::hex << 3.4 << std::endl;
2、使用using关键字。
using std::cout;
using std::endl;
以上程序可以写成
cout << std::hex << 3.4 << endl;
3、最方便的就是使用using namespace std;这样命名空间std内定义的所有标识符都有效(曝光)。就好像它们被声明为全局变量一样。那么以上语句可以如下写:
cout << hex << 3.4 << endl;
因为标准库非常的庞大,所程序员在选择的类的名称或函数名时就很有可能和标准库中的某个名字相同。所以为了避免这种情况所造成的名字冲突,就把标准库中的 一切都被放在名字空间std中。但这又会带来了一个新问题。无数原有的C++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。
所以就有了
命名空间std封装的是标准程序库的名称,标准程序库为了和以前的头文件区别,一般不加".h"
声明该文件使用C++标准库 吧!
比如 #include using namespace std; void main() { cout << "hello!" << endl; } 如果不用using namespace std;这句,那么 std::cout << "hello!" < 这是名字空间的问题!具体参看有关书籍吧,新版的C++ 书应该都有介绍的! --------------------------------------------------------------- using 指示符! 这是个名字空间问题,是标准C++引入的新概念! 具体在《C++Primer》第8.6节有详细说明! --------------------------------------------------------------- 因 为标准库非常的庞大,所程序员在选择的类的名称或函数名时就很有可能和标准库中的某个名字相同。所以为了避免这种情况所造成的名字冲突,就把标准库中的一 切都被放在名字空间std中。但这又会带来了一个新问题。无数原有的C++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。 所以就有了 --------------------------------------------------------------- 名字空间,实质上也是为了方便程序在不同平台上正确的运行。 --------------------------------------------------------------- namespace是为了解决C++中的名字冲突而引入的。 什么是名字冲突呢?比如,在文件x.h中有个类MyClass, 在文件y.h中也有个类MyClass,而在文件z.cpp中要同时 引用x.h和y.h文件。显然,按通常的方法是行不能的, 那怎么办呢?引入namespace即可。例如: 在x.h中的内容为 // x.h namespace MyNamespace1 { class MyClass { public: void f(); private: int m; } }; 在y.h中的内容为 // y.h namespace MyNamespace2 { class MyClass { public: void f(); private: int m; } }; 然后在z.cpp中引入x.h和y.h // z.cpp #include "x.h" #include "y.h" void z::f() { //声明一个文件x.h中类MyClass的实例x MyNamespace1::MyClass x; //声明一个文件x.h中类MyClass的实例x MyNamespace2::MyClass y; //调用文件x.h中的函数f x.f(); //调用文件y.h中的函数f y.f(); } 名字空间实质上是一个作用域。 |
using namespace std 和 using std::
using namespace std 和 using std::
using namespace std;//引入名字空间的所有内容,不推荐这样写
using std::cout; //分别引入,需要用哪个引用哪个,保证程序中名称的唯一性
using std::endl;
C++语言是从C语言发展起来的,因此有很多借鉴的地方。当C++语言推出但尚 未标准化以前(98年才标准化),市场上已经有了很多版本的程序库了,各库林立,导致互相应用时出现了一个很难调和的难题,那就是命名冲突,又称名空间泛 滥。比如某个库写了个函数line(int x,int y);不巧另外一个库又写了个类class line;这下编译器该匹配哪个呢?只好取决于哪个库文件先被引用到文件中,并且把另外一个完全屏蔽掉。这显然不是一个好的方法。在标准库的产生过程中, 这个问题被提了出来。为此,标准库组织决定在标准库中引入名空间的概念,所有标准库的组件都在名空间std中定义,由用户手动引入到程序中,这样就让编译 器知道,当遇到一个可能冲突的名称时,以标准库中定义的名称为主,如果想用标准库外定义的名称,那程序员需要自己注明另外的名空间,从而达到消除名空间泛 滥的目的。
using namespace std;的写法引入了名空间的所有内容,这是一种简单但不保险的做法,是标准库组织不推荐这么做的。因为这样引入了所有的组件函数名,相当于重新引发了名字空间泛滥的问题。为此,好的做法应该是分别引入,当你仅仅需要使用标准库的cout和endl时,可以这样引入
using std::cout;
using std::endl;
这样就引入了名空间std中的一些程序中用到的组件而不是全部引入。如果程序中使用了某个标准库提供的算法,比如for_each,可以这样调用
std::for_each(...)
这样就保证了程序中的名称唯一性。
当然,大多数教科书都不是这样做的,因为书本上的例题简单,不会有名冲突危险,但是到软件公司里就未必了,你很难保证别人写的代码就不与标准库冲突,所以,平时的编程习惯还是很重要的。
所谓namespace,是指标识符的各种可见范围。C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
一 :
后缀为.h的头文件c++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,c++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。
因
此,当使用
二:
所谓namespace,是指标识符的各种可见范围。
C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
由于namespace的概念,使用C++标准程序库的任何标识符时,可以有三种选择:
1、直接指定标识符。例如std::ostream而不是ostream。完整语句如下:
std::cout << std::hex << 3.4 << std::endl;
2、使用using关键字。
using std::cout;
using std::endl;
using std::cin;
以上程序可以写成
cout << std::hex << 3.4 << endl;
3、最方便的就是使用using namespace std;
例如:
#include
#include
#include
using namespace std;
这样命名空间std内定义的所有标识符都有效(曝光)。就好像它们被声明为全局变量一样。那么以上语句可以如下写:
cout << hex << 3.4 << endl;
因为标准库非常的庞大,所程序员在选择的类的名称或函数名时就很有可能和标准库中的某个名字相同。所以为了避免这种情况所造成的名字冲突,就把标准
库中的一切都被放在名字空间std中。但这又会带来了一个新问题。无数原有的C++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。
所以就有了
命名空间std封装的是标准程序库的名称,标准程序库为了和以前的头文件区别,一般不加".h"
今天用了VISUAL C++写了个小程序(VS2005),很简单很简单的,但是就是编译不通过
出现一个奇怪的问题:错误 1 error C2668: “max”: 对重载函数的调用不明确
最初代码如下
我将这段代码放到VC++ 6.0下竟然通过了,程序运行也正常。这让我百思不得其解。后来终于弄明白了!
其实在std命名空间下还有一个MAX函数,而且实现的功能也是一样的……我昏。利用转到定义功能可以看到微软是怎么写MAX函数的。这里为了不被鄙视就不贴微软的代码了。
明白了为什么出现这个错误我们就改写代码如下:
这是我比较推荐的做法,因为C++ PRIMER, EFFECTIVE
C++上都是用这种方式的,但是谭浩强的书上都是一句using namespace
std;就搞定,我觉得蛮简洁的就一直用了,没想到带来那么多的问题,以前在友元函数上还碰到莫名的错误呢。
其实还有两个简单的解决方案,那就是把自己定义的函数改成其他的名字,或者直接用微软提供的函数。相信微软提供的效率绝对不会比我们写的低~
好了,就写到这了。希望大家养成良好的编程习惯,^-^
1)命名空间的意思! 2)
#include 等同于:
#include using namespace std; 具体点: std::cout , std::endl; (在没有.h 或者 using namespace std 情况下) cout , endl (在有.h 或者 using namespace std) 3) 意思"使用std(标准)名字空间"的意思;假若你包含了标准库的头文件(如:cmath,cassert,vector等),而你又不想在使用std名字空间任何东西时加上 "std::" 前缀,你就可以用 using 关键字来向编译器说明你将要引用哪个名字空间下的东西. 一旦出现了"using namespace std;"这一句,那么在该行所在的作用域内有效,不过你还可以用"作用域分辩符'::'"来引用全局的函数或变量类型. 4)使用名字空间。 使用名字空间是为了避免类名字的污染,这是因为你有可能会命名一些有相同类名但实际操作不太相同的类,如果放在一起,编译器就不知道到底该用谁,如果你把具有相同类名的类放在不同的名字空间里,调用时注明是哪个名字空间里的类,编译器就能清楚了。 详细内容建议看看《c++ primer》 5)表示用的是标准名字空间std 表示你所使用的一些函数,标准的对象(如cout)都是在名字空间std下面的 6)所谓的名字空间是标准c++中的一种机制,用来控制不同类库的冲突问题。 使用它可以在不同的空间内使用同名字的类或者函数! 如下 std::cout<<"hi"; //表示使用std名字空间中的cout而不是普通的cout; 如果用using namespace std; 就可以去掉 “std::“而表示使用标准std空间中的函数(加上后缺省使用std空间中的) std当然不是随便的,它是标准的! 当然你可以自己做,那个时候就是任意的了。 |
实际上就是告诉编译器,你类型是什么,在哪能找到。
using namespace std ; 这是遵循c++标准的 相反,"iostream.h" 则没有遵循c++标准 ,这是老式的命名方式 ,延承自C语言。
这是网上摘抄的一相关解释:
其实没有 < iostream.h > 这样的东西 --- 标准化委员会在简化非C标准头文件时用 < iostream > 取代了它。但又没有完全取消 < iostream.h > 的使用,并且很多编译器都同时支持 < iostream > 和 < iostream.h > ,造成现在的局面,老大(标准化委员会)确实有不得已的苦衷。
话说当年,在标准化委员会动手重建新的标准库的时候,遇到了问题。为了避免类名和函数名的冲突问题,引入了名字空间std。但无数现有的C++代码都依赖 于使用了多年的伪标准库中的功能,例如,声明在 < iostream.h > 和 < complex.h > 等头文件中的功能。现有软件没有针对使用名字空间而进行相应的设计或者升级,如果用std来包装标准库导致现有代码不能使用,那手底下的小弟(程序员)是 不会同意的。
标准化委员会为了拉拢人心,吸引更多的人入会,决定为包装了std的那部分标准库构建新的头文件名。将现有C++头文件名中的.h去掉,所以就出现了
< iostream.h> 和 < iostream >
等很多双胞胎。对于C头文件,采用同样方法但在每个名字前还要添加一个C,所以C的 旧的C++头文件是官方明确反对使用的,但旧的C头文件则没有(以保持对C的兼容性)。其实编译器制造商不会停止对客户现有软件提供支持,所以在可以预计的将来,旧的C++头文件还会嚣张一段时间。 如果能明白字符串头文件的使用,举一反三,其他的也差不多会用了。
|
http://blog.csdn.net/lytwell/article/details/5623859