从C到Cpp——十一、名称空间

一、传统名称空间的重要概念

1--声明区域:可以在其中声明变量的区域。对于声明在函数外的变量,其声明空间为所在文件;对于声明在代码块内的变量,其名称空间为所在的代码块

2--潜在作用域:从声明点开始,到其声明空间的结尾

3--作用域:变量对程序可见的区域

作用域是潜在作用域的子集,潜在作用域是声明空间的子集。

#include <iostream>
using namespace std;
int main(void)
{
    int a;
    cout<<a<<endl;
    if (1)
    {
        int a;
        cout<<a<<endl;
    }   
}

第一个定义的a的声明空间是main函数,潜在作用域是从定义开始到main函数结束,但其作用域还要去掉if{}语句,因为在if语句中,第一个a被隐藏了。

之所以有上述的性质,是因为C++关于全局变量和局部变量的规则定义了一个名称空间层次。

二、全新名称空间特性

1--

C++定义了一种新的生命区域来创建命名的名称空间,这样子可以提供一个声明名称的区域,避免同名冲突。名称空间定义的语法如下:

​​namespace NAME
{
 ......
}
​

这就定义了一个名称为NAME的名称空间。

2--名称空间的元素包括变量、结构和函数

下面定义了一个名称为student的名称空间

​namespace student
{
    int age;
    char name[40];
    struct grade{int math;int English;};
    void fetch();
}​

​

3--名称空间可以是全局的,可以在别的名称空间中,但不能在代码块中

4--名称空间是开放的,可以用相同方式继续添加名称,比如我要给上述的名称空间student添加变量和函数定义,可以继续写:
 

namespace student
{
    int classnum;
    void fetch()
    {    
        std::cout<<age<<std::endl;
    }
}

(这里输入输出函数要不要加std::前缀呢?如果namespace代码块的前面已经使用using namespace std,则不用加std::前缀,因为using的作用域包括namespace定义;当然,也可以直接在namespace中直接使用using,但那样using的作用域就被限制在花括号中!不过,using反正可以重复使用,不像#include <iostream>只能用一次,所以这么多写一点不要紧!)

5--使用名称空间

当然是使用解析域作用符,略!

三、如何正确地using和::?

1--using声明

using std::cout;

将cout添加到using所属的声明区域中去

2--using编译指令

等效于有条件地把出现相应名称的变量、结构和函数名添加相应的前缀,下面两段程序等效:

#include <iostream>
using namespace std;
namespace student
{
	int age=10;
}
int main(void)
{
	using namespace student;
	cout<<age<<endl;
	int age=20;
	cout<<age;
}
#include <iostream>
using namespace std;
namespace student
{
	int age=10;
}
int main(void)
{
	cout<<student::age<<endl;
	int age=20;
	cout<<age;
}

之所以说是有条件的,是因为函数块/代码块中定义的局部变量会覆盖student::age。

3--using声明和编译指令的差别!

先看下面这两段程序

#include <iostream>
using namespace std;
namespace student
{
    int age=20;
}

int main(void)
{
	using namespace student;
	int age=10;
	cout<<age;
}
#include <iostream>
using namespace std;
namespace student
{
    int age=20;
}

int main(void)
{
	using student::age;
	int age=10;
	cout<<age;
}

第一段age重复定义是合法的,但第二段是不合法的!这涉及到using和using namespace的区别。前者就好像在相应的代码块中声明了相应的名称一样,而后者保留了名称空间的层次独立性。

局部变量会覆盖名称空间变量,名称空间变量又会覆盖全局变量。

4--如何在using后使用全局变量?

已知名称空间变量会覆盖全局变量,对吧?但不管使用哪一种using,都可以用下面的方法来使用全局变量

在变量名前面加上::

#include <iostream>
using namespace std;
namespace student
{
    int age=20;
}
int age=10;
int main(void)
{
	using namespace student;
	cout<<::age;
}

三、名称空间的其他性质

1--可以对名称空间进行嵌套

namespace student
{
    int age;
    char name[40];
    namespace grade
    {    
        int math;
        int english;
    }
    
}

使用时,如下操作即可:

student::grade::math

2--在名称空间中使用using声明

using namespace student_inf
{
    using student::age;
}

这么做会使student_inf::age和student::age等效。为同一变量的不同名称

3--在名称空间中使用using namespace编译指令

​using namespace student_inf
{
    using namespace student;
    int classnum;
}
​

这么做,可以让下面两个操作等价

using namespace student_inf
using namespace student_inf;
using namespace student;

编译指令具有传递性!

4--没有定义名称的名称空间等价于链接性为内部的静态变量!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值