C++ | 命名空间

命名空间,也就是名称空间/名字空间,注意需要的头文件是 iostream ,而不是 iostream.h ,后者是旧版本的 C++ 头文件,并不支持命名空间。

目录:

为什么要有命名空间?

它的作用主要体现在,编写大型程序或将多个厂商现有的代码组合起来,他会使得更容易,更易于组织。
比如说,有两个已经封装好的产品,他们呢,都有一个名叫 func() 的函数,调用这个函数的时候,编译器将不知道使用哪个函数。
这时候我们可以将其划定一片区域,即将每个厂商的产品封装起来,如第一个厂商的产品放到一个叫 SUST 的名称空间中,第二个厂商的产品放到一个叫 ZJU 的名称空间中,这样便能区分开来了。

使用方法

就像上面举出的例子,我们有了两个命名空间,那如何放入呢?
如下:

#include <iostream>

namespace <namespace name> {
    <declarations>
}

具体:

#include <iostream>

namespace SUST { // 名叫 SUST 的命名空间
    void func() {
        // ...
    }
}

namespace ZJU { // 名叫 ZJU 的命名空间
    void func() {
        // ...
    }
}

再来看调用,需要中间加两个冒号:
当使用 SUST 厂商的 func 时:

SUST::func();

当使用 ZJU 厂商的 func 时:

ZJU::func();

当然,不仅仅是函数,还有变量、类,都可以包括在一个命名空间中。

使用 std(使用全部与个别)

我们目前使用的大多函数,都被包括在一个标准命名空间中—— std ,例如我们知道的 coutcin 、还有控制符 endl等。
也就是说,当我们输入输出时,并不是简单的输入输出即可,而是需要写上名称空间。如以下这句输出函数:

std::cout << "hello world!" << std::endl;

使用全部名称

辣么问题来了,有两点,第一,我每次都要这么写,这就很麻烦了啊,第二,之前的版本(iostream.h),是没有名称空间的,现在要将之前的代码转换过来,要修改的地方就很多了。于是,一条编译指令应运而生:

using namespace std;

这行代码表明,可以使用 std 名称空间中所有定义的名称,且不需要使用 std:: 前缀。

使用所需的名称

当然,这会存在潜在的问题(我遇到过似乎...有时候取的变量名称会和std中的重复,我以前的编译器会报错,但是似乎现在g++更新了以后就不会了)。最好的做法是,需要什么就声明什么,例如我们要使用 coutcinendl

using <qualifier>::<name>;

也就是:

using std::cout;
using std::cin;
using std::endl;

这使得 coutcinendl 可用。

// 当然,之后应该会再加一些吧,因为后面第九章似乎还会讲到名称空间,目前还没看到,之后补充。

命名空间的嵌套

如果一个命名空间内,有两个名称相同的变量呢?要如何加以区分?这就可以使用嵌套了。
如,在 SUST 这个名称空间中,有两个 func 函数,可以这么使用:

namespace SUST {
    void func() {
        // ...
    }
    namespace test {
        void func() {
            // ...
        }
    }
}

调用时:

SUST::func();
SUST::test::func();

(话说也不知道是不是真的有场景会用到嵌套...emmmm先写上再说)

以下为总的一段:

#include <iostream>

using std::cout;
using std::cin;
using std::endl;

namespace SUST {
    void func() {
        cout << "SUST" << endl;
    }
    namespace test {
        void func() {
            cout << "test SUST" << endl;
        }
    }
}

namespace ZJU {
    void func() {
        cout << "ZJU" << endl;
    }
}

using namespace SUST;
using namespace ZJU;

int main(int argc, const char * argv[]) {
    SUST::func();
    SUST::test::func();
    ZJU::func();
    return 0;
}

运行结果:

SUST
test SUST
ZJU

总结

命名空间使得我们的变量、函数、类有了域,将他们局限在了一个域之内。在变量名/函数名重复时,可以区分他们属于哪个命名空间,加以辨别。在大型工程中应该会很好用。

哈哈哈哈哈哈