C++命名空间

C++关键字认识

image

命名空间

先看一个例子

定义一个rand变量,然后打印 ,这是没问题的

image

但是如果我们包含头文件 stdlib.h呢?

就会出现重定义问题
image

这是为什么呢?

因为stdlib里面本来就有一个函数叫 rand()

所以当包含了头文件之后,链接的时候会发现 rand重复定义了 --这就是命名冲突问题

C语言怎么解决这个问题呢? 只能改名字

C++注意到了这个问题,所以才有了命名空间这一说

命名空间的定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。

:: 域作用限定符

命名空间就是一个域,类似于全局域 也有局部域

命名空间既然是一个域,那么就可以定义变量,定于类型(结构体等),定义函数等

::用于访问域,前面是域的名字,后面是访问的内容

命名空间 :: 访问内容

如:

namespace test
{
    int a=10;
}
int main()
{
    printf("%d\n",test::a);//访问 test命名空间里的变量a
    return 0;
}

命名空间域的变量生命周期是全局,但是它属于该命名空间域

全局域也是一个域,里面有定义的全局变量之类的东西

回到上面的问题,rand命名冲突
image

int main()
{
    printf("%d\n",rand);//默认先找改局部(代码块内)
                        // 然后去找全局
    printf("%d\n",暴龙战士::rand);//这样是直接去暴龙战士命名空间去找
    // :: 是访问符号
    return 0;
}

注意

  • 同一个域不可以定义相同名字的变量
  • 而不同的域可以定义相同名字的变量
  • 局部有 先访问局部(局部优先)
  • 如果想访问全局域的内容:直接加一个 :: 前面不加命名空间,即空白,就是默认访问全局域

如下代码:

int a=0;
int main()
{
    int a=10;
    printf("访问局部的a:%d\n",a);
    printf("访问全局的a:%d\n",::a);
    return 0;
}

命名空间在项目中的意义

image

哪怕名字冲突,在使用过程中也没有影响

只需要指定命名空间就可以了

命名空间的嵌套

命名空间里可以放变量,函数,类型

还可以放命名空间(可以无限套娃)

namespace outer
{
    namespace inner
    {
        int rand=0;
        struct TreeNode{
            struct TreeNode* left;
            struct TreeNode* right;        
        }    
    }
}
int main()
{
    printf("%d\n",outer::inner::rand);//访问rand
    //访问结构体
    TreeNode
    return 0;
}

命名空间的合并

也就是有多个相同名字的命名空间

比如:如果在不同的文件中定义相同名字的命名空间

最后编译器会把相同名字的命名空间的合并到一起 同为一个命名空间

命名空间的使用

using namespace 空间名;

我们可以看到 每一次引用都需要加 空间名::访问内容

很麻烦!

如果在平时的使用,主要用于练习,不考虑冲突 可以使用该方法,就可以省很多麻烦,这样就直接展开了,不需要利用空间名修饰限定了

这时候 先在全局域找,如果没有就去展开的test命名空间里去找

using namespace test;
int main()
{
    //这时候 先在全局域找,如果没有就去展开的test命名空间里去找
    return 0;
}

所以 c++的 usging namespace std; 就好解释了

std是标准库的命名空间

由于怕别人与标准库冲突,所以把标准库的所有东西都放到了std命名空间里面去

所以如果你和标准库定义的某个东西名字一样,就不会冲突

但是如果引入using namespace std; 把标准库展开,就有冲突的风险了

命名空间名称+作用域限定符

如果不展开,不暴露出标准库命名空间,可能会看到这样的代码

(这样是更规范的写法)

#include<iostream>
int main()
{
    std::cout<<"hello"<<std::endl;
    return 0;
}

使用using将部分命名空间中的成员引入

一般把最常用的展开

using std::cout;
using std::cin;
using std::endl;
//这几个比较常用

int main()
{
    /****/
    /****/
    return 0;
}
posted @ 2024-01-21 22:55  夏季微凉"  阅读(37)  评论(0编辑  收藏  举报