C++ namespace解析

2014-11-24 07:22:09 · 作者: · 浏览: 0

看到网上很多人写了namespace的使用方法,我在此对大家的进行简单总结。通过此日志,可以快速掌握namespace的原理以及用法。

关于C++ namespace,我们需要回答如下几个问题:

1、什么是namespace?

2、为什么有namespace?也就是namespace的作用

3、namespace的使用方法有哪些?

(一)什么是namespace?

首先我们看看C++标准规范中对namespace的定义如下:

named-namespace-definition:

namespace identifier { namespace-body }

unnamed-namespace-definition:

namespace { namespace-body }

namespace包含两种,一种是有名的命名空间,一种是无名的命名空间。我们先看如下两个实例:

//有名的namespace的使用方法
#include 
  
   
namespace named_namespace{
    //变量
    int value = 1;
    //函数
    void Output() { std::cout << value << std::endl;}
    //结构体
    struct Test{
        int value;
        void Output() {std::cout << value << std::endl;}
    };
    //类
    class Object{
        public:
           void SetValue(const int& val){ value_ = val; }
           void Output() {std::cout << value_ << std::endl;}
        private:
           int value_;
    };
}

  

上面是有名的命名空间的使用方式,可以看出来,命名空间可以包含变量、函数、结构体以及类等,统统将他们包含进来。

\

上述是无命名空间的使用方式。只不过无命名空间是没有名字的。

(二)为什么有namespace?也就是namespace的作用

第一部分,我们讲述了namespace的具体定义形式,但是我们为什么要使用namespace呢?namespace能给我们实际变成过程中带来哪些好处呢?

namespace主要用于解决“命名冲突”问题。在大型项目开发中,可能有很多人同时进行编写代码,不同的模块可能使用了相同的全局变量,当系统集成的时候,就会发生命名冲突的问题。我们通过如下简单代码可以明白什么是命名冲突:

头文件head1.h定义如下:

int value = 1;

头文件head2.h定义如下:

double value = 2.2;

主函数定义如下:

#include 
  
   
#include head1.h
#include head2.h

int main(int argc, char** argv)
{
    std::cout << value << std::endl;

    return 0;
}
  

编译错误信息如下:

\

从上面代码可以看出,value出现在两个头文件中进行定义了,主函数main中value发生了冲突,不能确定是哪一个头文件中的。上述只是一个简单的示例,当面对成百上千的头文件时候,很难避免相同名字的出现。

此时,namespace的作用就显现出来了,namespace是“命名空间”,从名字上就可以看出来,就是构成了一个空间,在空间里面的内容和空间外的内容无关,只和本空间内部的信息有关。简单点讲就是,namespace用于分割项目整个空间,使每一个空间相对独立,虽然相同的名字存在,但是他们处于不同的namespace中,就不会发生命名冲突。

上述发生错误的代码可以通过namespace进行解决:

头文件head1.h定义如下:

namespace head1{
    int value = 1;
}

头文件head2.h定义如下:

namespace head2{
    double value = 2.2;
}

主函数定义如下:

#include 
  
   
#include head1.h
#include head2.h

int main(int argc, char** argv)
{
    std::cout << head1::value << std::endl;
    std::cout << head2::value << std::endl;

    return 0;
}
  

运行结果如下:1 和 2.2

上面着重讲述了有名namespace的作用。

其实无名namespace的作用也是避免“命名冲突”。关于无命名空间,需要注意如下两点:

1、无名名字空间主要是保持代码的局部性

2、在C++编译器实现时,无名名字空间其实是有名字的,这个隐含的名字跟它所在编译单元名字相关。所以基于这一点,我们不能跨编译单元使用无名名字空间中的名字

(三)namespace的使用方法有哪些?

主要的使用方法有两种,一种是名字::XXX,第二种是using关键字。

第一种在上述的代码中已经进行过相应的演示。

第二种代码类似于using namespace std;这种方式,下面直接使用std空间里面的内容即可。虽然这种方式简单快捷,但是会有隐形的危险在代码里面,当两个不同的命名空间同时在一个文件中使用using 方式,相同名字就会发生冲突。