C++ namespace

Posted 呆呆象呆呆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ namespace相关的知识,希望对你有一定的参考价值。

命名空间

在学习c++的时候,看到很多程序中用了以下语句:

using namespace std;

1 为什么需要命名空间

命名空间是ANSI C++引入的可以由用户命名的作用域,用来处理程序中常见的同名冲突。

在c++中有4层次的作用域:文件函数复合语句。在不同的作用域中可以定义名字相同的变量,互不干扰,便于系统区别他们。如下:

class A

public:
    void fun1();
private:
    int i;
;
void A::fun1()



class B

public:
    void fun1();
private:
    int i;
;
void B::fun1()


这样,他们就不会发生混淆。

但是,一个大型的应用软件,往往不是由一个人独立完成的,而是由若干不同的人合作完成的,不同的人分别完成不同的部分,最后组成一个完整的程序。假如不同的人分别定义了类,放在了不同的文件中,在主函数的文件中需要使用这些类时,就用#include指令将这些头文件包含进来。由于头文件是由不同的人设计的,有可能在不同头文件中用了相同的名字来命名所定义的类或函数。这样,程序中就会出现名字冲突。

以下面的程序为例,在People A.hPeople B.h分别定义类和函数:

//PeopleA.h
class Student
public:
    Student(int n, char s, string name)
    
        //.....
    
private:
    int num;
    string name;
    char sex;
;
int fun(int a, int b)

    return a + b;


//PeopleB.h
class Student

public:
    Student(int n, char s, string name)
    
        //.....
    
private:
    int num;
    char sex;
    string name;
;
int fun(int a, int b)

    return a + b;


假如在主程序中要用到PeopleA.h中的Student函数,需要在头文件中包含People A.h,同时要用到PeopleB.h中的Student函数,需要在头文件中包含PeopleB.h,如果主程序如下:

#include <iostream>
#include "People A.h"
#include "People B.h"
int main()

    Student stdu1(101, 18, "wang");
    cout << fun(5, 3) << endl;
    return 0;

这时程序就会出错,因为在预编译后,头文件中的 内容取代了对应的#include指令,这样就在同一个程序文件中出现了两个Student类和两个fun函数,显然是重复定义,这就是名字冲突,即在同一个作用域中有两个或者多个同名的实体。

2 什么是命名空间

所谓命名空间,实际上就是一个由程序设计者命名的内存区域。程序设计者可以根据需要制定一些有名字的空间域,把一些全局实体分别放在各个命名空间中,从而与其他全局实体分隔开来。如:

namespace AA

    int a;
    double b;

namespace是定义命名空间所必须写的关键字,AA是自己制定的命名空间的名字。如果在程序中要使用a和b,必须加上命名空间名和作用域分辨符::,如AA::aAA::b,这种用法称为命名空间限定。
命名空间的作用是建立一些互相分隔的作用域,把一些全局实体分隔开来,以免产生名字冲突。

3 使用命名空间解决名字冲突

如下程序为例:

//PeopleA.h
namespace PeopleA
class Student
public:
    Student(int n, char s, string name)
    
        //.....
    
private:
    int num;
    string name;
    char sex;
;
int fun(int a, int b)

    return a + b;


//PeopleB.h
namespace PeopleB
class Student

public:
    Student(int n, char s, string name)
    
        //.....
    
private:
    int num;
    char sex;
    string name;
;
int fun(int a, int b)

    return a + b;


#include <iostream>
#include "People A.h"
#include "People B.h"
int main()

    PeopleA::Student stdu1(101, 18, "wang");
    cout << PeopleA::fun(5, 3) << endl;
    PeopleB::Student stdu1(101, 18, "wang");
    cout << PeopleB::fun(5, 3) << endl;
    return 0;

4 使用命名空间成员的方法

在引用命名空间成员时,要用命名空间名和作用域分辨符对命名空间成员进行限定,以区别不同的命名空间中的同名标识符。即:

命名空间名::命名空间成员名

c++提供了一些机制,能简化使用命名空间的使用:

4.1 使用命名空间别名

可以为命名空间起一个别名,用来替代较长的命名空间名,可以用一个较短的别名替代它。如:

namespace PeopleA
namespace PA = PeopleA

4.2 使用using命名空间成员名

可以直接使用命名空间部分的成员,using后面的命名空间成员名必须是由命名空间限定的名字,如:

using AA::i;
或者
using std::cout;

随后的代码中,在使用cout时就可以不用加上命名空间名称作为前缀,但是std命名空间中的其他项目仍然需要加上命名空间名称作为前缀

4.3 使用using namespace命名空间名

可以使用using namespace指令,这样在使用命名空间时就可以不用在前面加上命名空间的名称。这个指令会告诉编译器,后续的代码将使用指定的命名空间中的名称。

如:

using namespace AA;

声明了在本作用域中要用到命名空间AA中的成员,在使用该命名空间的任何成员时都不必再使用命名空间限定。

5 无名的命名空间

c++中可以声明无名的命名空间,如:

namespace 

    void fun()
    
        //....
    

由于命名空间没有名字,在其他文件中显然无法引用,它只在本文件的作用域有效。若无名命名空间的成员fun函数的作用域为文件A,在文件A中使用无名命名空间的成员,不用也无法用命名空间名限定。

6 标准命名空间std

标准C++库中的所有标识符都是在一个名为std的命名空间中定义的,或者说标准头文件中的函数、类、对象和模板实在命名空间std中定义的。一般用using namespace语句对命名空间std进行声明,这样可以不必对每个命名空间成员一一进行处理,在文件的开头加入如下语句:

using namespace std;

这样,在std中定义和声明的所有标识符在本文件中都可以作为全局变量来使用。

7 不连续命名空间

命名空间可以定义在几个不同的部分中,因此命名空间是由几个单独定义的部分组成的。一个命名空间的各个组成部分可以分散在多个文件中。

所以,如果命名空间中的某个组成部分需要请求定义在另一个文件中的名称,则仍然需要声明该名称。下面的命名空间定义可以是定义一个新的命名空间,也可以是为已有的命名空间增加新的元素:

namespace namespace_name 
   // 代码声明

8 嵌套的命名空间

命名空间可以嵌套,您可以在一个命名空间中定义另一个命名空间,如下所示:

namespace namespace_name1    
    // 代码声明
    namespace namespace_name2 
        // 代码声明   
     

您可以通过使用 :: 运算符来访问嵌套的命名空间中的成员:

// 访问 namespace_name2 中的成员
using namespace namespace_name1::namespace_name2;
// 访问 namespace_name1 中的成员
using namespace namespace_name1;

在上面的语句中,如果使用的是 namespace_name1,那么在该范围内 namespace_name2 中的元素也是可用的,如下所示:

#include <iostream>
using namespace std;
 
// 第一个命名空间
namespace first_space
   void func()
      cout << "Inside first_space" << endl;
   
   // 第二个命名空间
   namespace second_space
      void func()
         cout << "Inside second_space" << endl;
      
   

using namespace first_space::second_space;
int main ()

 
   // 调用第二个命名空间中的函数
   func();
   
   return 0;

当上面的代码被编译和执行时,它会产生下列结果:

Inside second_space

Last 参考文献

C++ 命名空间-namespace作用与使用方法详解_cherishinging的博客-CSDN博客_c++ 命名空间

C++ 命名空间 | 菜鸟教程

以上是关于C++ namespace的主要内容,如果未能解决你的问题,请参考以下文章

C++笔记--namespace概念(1-1)

C++ 命名空间 (namespace)

02C++namespace命名空间

c++模板使用及常见问题

namespace的作用及用法

using namespace std