C++入门(2)——命名空间详解

一、命名空间的引入

        在C语言中,如果在已经包含了头文件的情况下,我们想要定义一个名为“print”的变量,是没有办法实现的。这是因为头文件中的“print”函数和我们想定义的变量产生了“命名冲突”。

例如:

#include
#include
int printf=0;
int main()
{
    return 0;
}

  注意!如果把产生命名冲突的变量定义在函数内部,则编译器不会报错。因为头文件的展开是在全局域。如果定义在函数内部则是定义在了局部域,此时编译器会遵循“局部优先”原则。

        这样的问题在大型的项目中尤为突出。一个大的项目会被分给很多个程序员去做,每个人各自写自己部分的代码都没有问题,但是当所有代码合在一起的时候,这样的命名冲突是难以避免的。为了解决这个问题,C++引入了——命名空间(namespace)的概念。

二、命名空间的实质

        命名空间为什么能够解决“命名冲突”的问题呢?

        事实上,命名空间定义了一个命名空间域(“域”是一个语法的概念)。而这个“域”,是在全局域里面的。命名空间解决“命名冲突”的原理是影响编译器查找其内容的规则   。

注意!命名空间不影响变量的存储位置和生命周期。命名空间里的变量仍然是全局变量,储存在静态存储区中。只是我们定义的“namespace”就像筑起一道隐形的围墙一样隔绝了编译器的查找,除非你通过特殊手段确定了你要找的东西在一个确定的命名空间里,才可以顺藤摸瓜找到它。(查找方法在后面会讲到。)

三、命名空间的定义

1.一般命名空间的定义

格式:

namespace king//namespace  +命名空间的名字,此处名字为“king”
{
    ...//这里可以定义变量、函数以及类型。
}

提示:如果定义了结构体,后面引用的时候要注意域限定符的位置。后面会讲到。

注意!命名空间展开后的内容是在全局域里边的,因此不能在函数内定义。因为函数内部是一个局部作用域。

2.命名空间的嵌套定义

        命名空间可以嵌套(即在一个namespace里面定义另一个)

namespace N
{
    int a,b;
    namespace N1
    {
        int a,b;
        namespace N2
        {
            int a,b;
        }
    }

}

        在不同的或者不同级的命名空间中使用一样变量名是不会冲突的。想象一下不同的院落,或者同一个院落里不同的房间,都是可以独立使用的。但是在使用的时候形式会有些区别。

3.同名命名空间的合并

        C++的同一个project中是允许同时存在多个同名字的命名空间的。因为编译器最终会将他们合成到同一个命名空间里面。

注意!只有同级的同名命名空间会被合并成同一个命名空间。

namespace N1
{
    namespace N1
    {
    }
}

这两个命名空间N1不会被合并。使用时也不一样。

四、命名空间的使用

        命名空间内定义的变量、函数等是不可以直接被使用的。其使用有三种方法,以下小标题为使用格式。

说明:        “::”——作用域限定符。表示作用域及其所属关系。

                   假设已经定义了一个名为“N”的命名空间。要引用N中的变量a。

1.命名空间 ::引用成员;    N::a)

int main()
{
    printf("%d",N::a);
    return 0;
}

2.using ::引用成员;(using N::a)

using N::a;
int main()
{
    printf("%d",a);
    return 0;
}

注意!此格式使用于函数前面,只将N中的a展开,此后可以直接引用N中的a。但是如果还想使用N中的b,b仍然不能直接引用。

3.using namespace 命名空间;(using namespace N)

using namespace N;
int main()
{
    printf("%d",a);
    printf("%d",b);
    return 0;
}

        这种用法相当于将N中的全部内容都展开。类似于把围墙拆除,里面所有东西都暴露出来。之后引用N中的一切内容都可以直接引用。

注意!这种方法可以在日常练习中使用以图方便,但在正式的项目里不建议使用。因为这么做使C++的命名空间的引入失去了意义——它仍然无法解决命名冲突问题。

———————————————————————————————————————————

补充:如果是引用结构体,格式应该是   struct N::结构体名字  +变量名;例如,struct N::SLnode node;

如果是上文所提的嵌套定义,用第一种方法引用N2时应为——N::N1::N2::引用成员;

不同级的同名命名空间,以上文为例,低级的应为N1::N1::引用成员

小结

命名空间的引入是为了解决C语言中命名冲突的问题。

命名空间的作用原理是影响编译器的查找规则,而不影响内容的生命周期和存储位置。命名空间里的内容存储在静态区。

命名空间只能在全局域定义。

命名空间可以嵌套定义。同级同名命名空间可以合并。

你可能感兴趣的:(C++小白成长历程,c++,开发语言,学习)