命名空间概念

命名空间的出现是为了防止标识符的重定义,比如在合并多个文件后,可能会出现多个文件使用了同一个变量名。再比如你的变量名与某一函数相同。(命名空间中可以定义函数)


命名空间原理

命名空间的原理就是由编译器帮我们给相同作用域内的变量和函数标识符添加作用域独属的前缀,因此不同作用域的同名变量/函数能被区分开,实际上不同作用域的同名变量/函数的名字在编译器看来已经不一样了。

注意:

  1. 实际上,命名空间就是作用域,只不过是我们自己定义的有名字的作用域。
  2. 特别注意的是,c++规定命名空间针对的是全局变量,不能在main函数,类内等局部作用域中定义命名空间。

命名空间语法

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

char a = 'x';

struct ST
{
    int a;
};

void STinit() 
{
    cout << "STinit()" << endl;
}

namespace bit 
{
    char a = 'y';

    struct ST
    {
	char a;
    };

    void STinit()
    {
	cout << "namespace-STinit()" << endl;
    }
}
  • namespace是命名空间的关键字,bit是自己起的名字
  • 命名空间可以嵌套定义。等价于作用域嵌套嘛。
  • 在同一个大项目下,同名的命名空间会自动合并成一个命名空间

命名空间使用

共有三种方式去使用命名空间中的变量

通过作用域限定符::来使用

namespace bit
{
    int a = 5;
}

int a = 10;

int main() 
{
    printf("%d",bit::a);
}

要注意的是:对于结构体,要将bit::置于结构体名字之前不能置于struct之前,因为struct不是结构体名字而是关键字:

namespace bit
{
    int a = 5;

    struct ST {};
}

int a = 10;

int main() 
{
    struct bit::ST st;
}

使用using [命名空间名]::[要引入的成员名]

将命名空间中的成员y引入当前作用域(也就是这句话所在的作用域)。

像第一种方法那样,每次使用命名空间中的成员时,都要写成指定命名空间,这样会比较麻烦。因此我们使用using [命名空间名]::[要引入的成员名],可以将命名空间中的成员引入到当前作用域,以后使用时就不需要指定命名空间了而是直接使用(然而,当前作用域不能有同名成员,否则就与引入的成员重定义了)。

举个例子:

namespace bit
{
    int a = 5;

    struct ST {};
}


int main() 
{
    //int a = 10;会报重定义错误
    using bit::a;
    cout << a << endl;//不用再指定命名空间了
}

注意:

  • 将命名空间的成员引入后,该成员的作用域,生命周期,存储位置等都不改变,只是在当前作用域可以使用而已。
namespace bit
{
    int a = 5;

    struct ST {};
}


int main() 
{
    int& a = bit::a;//等价于using bit::a
    
    cout << a << endl;
    a = 100;
    cout << a << endl;

}

使用using namespace [命名空间名] 

类似于第二种方法,第三种方法会将命名空间中的变量全部引入进当前作用域,注意事项和第二种方法一样。但是最好不要使用这种方法,因为他会使命名空间失去意义。


补充

1.命名空间只影响作用域不会影响本来的生命周期。

2.关于命名空间比较有意思的原理性文章:.NET C#基础(6):命名空间 - 有名字的作用域 - HiroMuraki - 博客园

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐