欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++ 命名空间-namespace作用与使用方法详解

程序员文章站 2022-05-03 18:06:12
c++ 命名空间-namespace作用与使用方法详解,在学习c++的时候,看到很多程序中用了以下语句: using namespace std; 这表明使用了命名空间std,那么什么是命名空间?为...

c++ 命名空间-namespace作用与使用方法详解,在学习c++的时候,看到很多程序中用了以下语句:
using namespace std;
这表明使用了命名空间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.h和people 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;
}

假如在主程序中要用到people a.h中的student函数,需要在头文件中包含people a.h,同时要用到people b.h中的student函数,需要在头文件中包含people b.h,如果主程序如下:

#include 
#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::a,aa::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 
#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++提供了一些机制,能简化使用命名空间的使用:

1、使用命名空间别名

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

2 、使用using命名空间成员名

using后面的命名空间成员名必须是由命名空间限定的名字,如:
using aa::i;

3、使用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中定义和声明的所有标识符在本文件中都可以作为全局变量来使用。
以上是关于c++命名空间的知识总结,希望对大家有所帮助~~