Chinaunix首页 | 论坛 | 博客
  • 博客访问: 145722
  • 博文数量: 108
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 940
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-15 20:24
个人简介

反反复复

文章分类

全部博文(108)

文章存档

2014年(72)

2013年(36)

我的朋友

分类: C/C++

2013-03-30 16:00:28

命名空间std,using namespace std

 

 

 

在标准C++以前,都是用#include这样的写法的,因为要包含进来的头文件名就是iostream.h。标准C++引入了名字空间的概念, 并把iostream等标准库中的东东封装到了std名字空间中,同时为了不与原来的头文件混淆,规定标准C++使用一套新的头文件,这套头文件的文件名 后不加.h扩展名,如iostream、string等等,并且把原来C标准库的头文件也重新命名,如原来的string.h 就改成cstring(就是把.h去掉,前面加上字母c),所以头文件包含的写法也就变成了#include
    并不是写了#include就必须用using namespace std;我们通常这样的写的原因是为了一下子把std名字空间的东东全部暴露到全局域中(就像是直接包含了iostream.h这种没有名字空间的头文件 一样),使标准C++库用起来与传统的iostream.h一样方便。如果不用using namespace std;使用标准库时就得时时带上名字空间的全名,如std::cout << "hello" << std::endl;
     #include "iostream" 与 #include的区别:前者先在当前目录找iostream文件,找不到再去系统头文件路径找,后者反之。因此,做为一个良好的习惯,在包含系统头文件时尽量用<>,而在包含自己的工程中的头文件时用""

    不一样,前者没有后缀,实际上,在编译器include文件夹里面可以看到,二者是两个文件,打开文件就会发现,里面的代码是不一样的。

    后缀为.h的头文件c++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,c++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。

    因此,当使用时,相当于在c中调用库函数,使用的是全局命名空间,也就是早期的c++实现;当使用的时候,该头文件没有定义全局命名空间,必须使用namespace std;这样才能正确使用cout。

#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++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。  

     所以就有了等等这样的头文件,一个是为了兼容以前的C++代码,一个是为了支持新的标准。

    命名空间std封装的是标准程序库的名称,标准程序库为了和以前的头文件区别,一般不加".h"

 

 

 

 

using namespace std的作用
2009-05-06 16:23


声明该文件使用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++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。

       所以就有了等等这样的头文件,一个是为了兼容以前的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中。

一 :

是不一样,前者没有后缀,实际上,在你的编译器include文件夹里面可以看到,二者是两个文件,打开文件就会发现,里面的代码是不一样的。

后缀为.h的头文件c++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,c++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。

因 此,当使用时,相当于在c中调用库函数,使用的是全局命名空间,也就是早期的c++实现;当使用< iostream>的时候,该头文件没有定义全局命名空间,必须使用namespace std;这样才能正确使用cout。

二:

所谓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++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。   

         所以就有了等等这样的头文件,一个是为了兼容以前的C++代码,一个是为了支持新的标准。

命名空间std封装的是标准程序库的名称,标准程序库为了和以前的头文件区别,一般不加".h"

 

 

今天用了VISUAL C++写了个小程序(VS2005),很简单很简单的,但是就是编译不通过
出现一个奇怪的问题:错误 1 error C2668: “max”: 对重载函数的调用不明确

最初代码如下

#include <iostream>
using namespace std;

template
<typename T>
T max (T a,T b)
{
return ((a>b)?a:b);
}

void main()
{
double x,y;
cin
>>x>>y;
cout
<<"Max number is "<<(max(x,y))<<endl;
cin
>>x;
}


     我将这段代码放到VC++ 6.0下竟然通过了,程序运行也正常。这让我百思不得其解。后来终于弄明白了!
     其实在std命名空间下还有一个MAX函数,而且实现的功能也是一样的……我昏。利用转到定义功能可以看到微软是怎么写MAX函数的。这里为了不被鄙视就不贴微软的代码了。
     明白了为什么出现这个错误我们就改写代码如下:

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

template
<typename T>
T max (T a,T b)
{
return ((a>b)?a:b);
}

int main()
{
double x,y;
cin
>>x>>y;
cout
<<"Max number is "<<(max(x,y))<<endl;
cin
>>x;
}


     这是我比较推荐的做法,因为C++ PRIMER, EFFECTIVE C++上都是用这种方式的,但是谭浩强的书上都是一句using namespace std;就搞定,我觉得蛮简洁的就一直用了,没想到带来那么多的问题,以前在友元函数上还碰到莫名的错误呢。
     其实还有两个简单的解决方案,那就是把自己定义的函数改成其他的名字,或者直接用微软提供的函数。相信微软提供的效率绝对不会比我们写的低~
     好了,就写到这了。希望大家养成良好的编程习惯,^-^

 

 

 

using namespace std是什么意思
2009-03-05 10:30


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 的用法
2009-08-19 23:57


实际上就是告诉编译器,你类型是什么,在哪能找到。  

常用的是using   namespace   std,就是说用C++的标准名字空间。  

你也可以引用你自己的名字空间。比如说:  

import   "C://MyTest//test.tlb"  
using   namespace   CMyTest  

就可以引用CMyTest内的各个类型名  

因 为标准库非常的庞大,所程序员在选择的类的名称或函数名时就很有可能和标准库中的某个名字相同。所以为了避免这种情况所造成的名字冲突,就把标准库中的一 切都被放在名字空间std中。但这又会带来了一个新问题。无数原有的C++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。  

       所以就有了等等这样的头文件,一个是为了兼容以前的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 ;

这是遵循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++头文件还会嚣张一段时间。

    如果能明白字符串头文件的使用,举一反三,其他的也差不多会用了。

    是旧的C头文件,对应的是基于char*的字符串处理函数;

    是包装了std的C++头文件,对应的是新的strng类;

    是对应旧的C头文件的std版本。


    跑远了,言归正传。如果你的编译器都同时支持 < iostream > 和 < iostream.h >,那使用 #include < iostream >,得到的是置于名字空间std下的iostream库的元素;如果使用 #include < iostream.h >,得到的是置于全局空间的同样的元素。在全局空间获取元素会导致名字冲突,而设计名字空间的初衷正是用来避免这种名字冲突的发生。还有,打字时 < iostream > 比 < iostream.h > 少两个字,所以我会使用 < iostream >

 

 

using namespace std

  所谓namespace,是指标识符的各种可见范围。C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
   一 : 格式不一样,前者没有后缀,实际上,在你的编译器include文件夹里面可以 看到,二者是两个文件,打开文件就会发现,里面的代码是不一样的。 后缀为.h的头文件c++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,c++标准为了和C区别开, 也为了正确使用命名空间,规定头文件不使用后缀.h。 因 此,当使用时,相当于在c中调用库函数,使用的是全局命名空间,也就是早期的c++实现;当使用< iostream>的时候,该头文件没有定义全局命名空间,必须使用namespace std;这样才能正确使用cout。
  二: 所谓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++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。 所以就有了和等等这样的头文件,一个是为了兼容以前的C++代码,一个是为了支持新的标准。 命名空间std封装的是标准程序库的名称,标准程序库为了和以前的头文件区别,一般不加".h"
  简便理解:
  98年以后的c++语言提供一个全局的命名空间namespace,可以避免导致全局命名冲突问题。举一个实例,请注意以下两个头文件:
  // one.h
  char func(char);
  class String { ... };
  // somelib.h
  class String { ... };
  如果按照上述方式定义,那么这两个头文件不可能包含在同一个程序中,因为String类会发生冲突。

 http://blog.csdn.net/lytwell/article/details/5623859

阅读(646) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~