C++|namespace

1.介绍

namespace是C++中的关键字,作用是标记一块命名空间的作用域,我们可以使用对应操作来使用命名空间内的定义.

namespace my_std1
{
	int a = 1;
	int b = 1;
}
int a = 2;

在namespace代码块的内部我们只能进行函数,变量以及结构体,枚举之类的定义行为

2.使用

namespace内的定义想要使用起来也是很简单我们只需要使用(::)来进行操作

int d;
d = ::a;       //此时a==2
d = my_std1::a  //此时a==1

将(::)写在定义内容的左边,然后再(::)右边写上空间的名称,即可实现对namespace内定义的使用

对于(::)操作,它类似于将你的查找关键字的范围限制到命名空间中同时开放对此次操作的作用域

namespace内无法进行定义以外的操作,而定义操作都被允许(宏定义不算严格意义上的定义它本身不受任何操作的影响,namespace自然也无法影响)

namespace my_std1 {
	int sum(int n1,int n2){
        return n1 +n2; 
    }
    struct node{
        int num;
    };
    enum day{
        monday
    };
    union snum{
        int num;
    };
    namespace son_space{
        int a;
    }
}
//函数,结构体,联合体,枚举都可以
//命名空间本身的定义也可以

嵌套命名空间只需要嵌套标记就可以使用

son_space::a = 1;//无法这样直接使用因为son_space的定义不在全局
my_std1::son_space::a = 1;//这样嵌套是正确的,多层只需要依次嵌套然后解开就可以了

当出现了两个相同命名空间时它们被看作是一个命名空间

namespace my_std2{
    int a;
}
namespace my_std2{
    int b;
}
//此时里面既有变量a也有b


//这样也可以
namespace my_std4{
    int a;
    namespace my_std4{
        int b=1;
    }
}
namespace my_std4 {
    int b=2;
    int c;
}
//my_std4内的my_std4不会和外部的my_std结合
//需要单独访问,这是因为my_std4没有my_std4的定义
//所以我们可以在内部进行定义
//访问时依旧哦按照对应方式
my_std4::my_std4::b == 1;
my_std4::b == 2;

在同一个作用域内的定义行为自然可以直接使用定义域内的内容

namespace my_tad3{
    int val =10;
    int judge(int n){
        if(n>=val)
        return ture;

        return flase;
    }
//里面可以直接使用
}
int judge(int n){
    if(n>=my_std3::val)
    return ture;

    return flase;
}
//外面就需要引用了

使用using关键字来可以直接在当前全局内展开命名空间

using namespace my_std1;
b = 10;
son_space::a = 10;
//可以直接访问其中的定义内容
using namespace son_space;
//也可以进一步展开,不过此时会出现问题,此空间内出现了两个相同名称的全局变量,还记得他们中都有
//一个a吗,此时会出现问题,不过此时编译器并不会报错,而是在你使用时返回不明确错误

也可以进行以下展开

using namespace my_std1::son_space;
//这样可以精准展开
//不过此时依旧无法直接使用 son_space::a
//因为虽然它被展开,但是son_space的定义是在my_std1
//不过此时也不需要这么做

对于单个定义的展开也是可以的

using namespace my_std1::son_space::a;
//这样只展开单个元素

 命名空间展开的生效范围取决于你进行操作的范围当你对全局范围进行展开时,它的作用范围是全局,当你对局部进行展开时它的作用范围是局部

3.关键字行为

命名空间实际上是一块作用域,他是一块特殊的作用域,通常来讲,除了变量以外的其他定义操作是不能在全局作用域外定义的,而namespace创建的作用域内可以定义这些内容,而它本是不能在除命名空间和全局以外的其它作用域内定义.

简单来讲就是: 在C++中的定义行为(除变量以外)都可以在命名空间内的作用域中进行

在命名空间内定义的变量本质还是全局变量,它的生命周期是整个程序,只不过它的作用域是只有那一块,不过当它被using展开后,假如有其他同名的全局变量它不会直接报错,而是会在使用时,返回内容不确定

对于命名空间的内容根据我个人的理解,有一个较好的理解方式,对于作用域而言通常只有包含被包含和不相交的关系,而假如我们带入分配作用域的概念,那么作用域就有了相交的的关系,这实在是非常抽象,因为同名变量的优先级取决于作用域的大小,作用域小的优先级高,作用域大的优先级低,如果只有前面三种关系的话,那么两个作用域不同的同名变量的作用域有明确的,不相交,或者大或者小的关系,而如果带入相交的关系那么问题就变得完全不可控,这是所不能接受的,而如果我们抛弃分配的看法,认为对于命名空间内的定义来说,他的作用域始终不变,using和(::)的操作都只是进行一个分配式的访问,即借用的话,那么一切就很好解释了,using展开的内容即使冲突也不会直接报错,而是在访问的时候返回不确定,这就是因为在编译器看来即使它展开过了,但是他的作用域依旧不变,所以也就不会出现两个相同的作用域的同名定义出现,只不过是当我们想要访问时,出现了两个可选项所以报错了,这里只要有一个普通的定义和一个借用的定义就会报错,无关优先级,这是由于对于借用的内容它期望你在使用时只使用它,它的优先级可以看作是“非常高”以至于只要有其他的定义就会报错,如果说using是整个程序在借用定义内容的话那么(::)就是单次访问在借用定义,有什么区别?当然有,如果是程序在借用那么不会每次操作都使用,而单次借用就是再说我现在就要使用里面的定义,所以它的查找范围会在作用域之中。

对于全局借用操作由作用域不好确定,所以默认设置优先级为特殊,当出现多个可能性时会直接报错,而单次借用操作查找范围会在作用域之中,所以自然不会出现问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值