【C++】C++小知识 - 名字空间详解

名字空间详解

目录

 

1.名字空间指令

1.1 问题

1.2 步骤

1.3 完整代码

2 名字空间声明

2.1 问题

2.2 步骤

2.3 完整代码

3 名字空间声明与指令的区别

3.1 问题

3.2 步骤

3.3 完整代码

4 无名名字空间

4.1 问题

4.2 步骤

4.3 完整代码

5 多层名字空间

5.1 问题

5.2 步骤

5.3 完整代码


1.名字空间指令

1.1 问题

名字空间指令表示在当前作用域中对某个名字空间的所有成员可见,而外层作用域的同名实体将被隐藏。

1.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:使用名字空间指令

代码如下所示:

#include 
namespace ns {
    int var = 0;
    void fun (void){
        int a = 10;
        std::cout << "a = " << a << std::endl;
    }
}
using namespace ns;
int main(int argc, const char * argv[])
{
    
    std::cout << "ns::var = " << var << std::endl;
    fun();
    return 0;
}

上述代码中,以下代码:

using namespace ns;

指定ns名字空间中的所有成员,在该行语句以下的所有语句中均可直接使用。

上述代码中,以下代码:

std::cout << "ns::var = " << var << std::endl;

变量var是ns名字空间中的变量,由于使用了名字空间指令,所以可以直接使用,其前面无需添加作用域限定符ns::。

步骤二:使用名字空间指令引发的冲突代码如下所示:

#include 
namespace ns {
    int var = 0;
    void fun (void){
        int a = 10;
        std::cout << "a = " << a << std::endl;
    }
}
namespace ns1 {
    int var = 0;
}

如果有两个名字空间,ns和ns1,其中都有整型变量var,此时对它们同时使用名字空间指令using将引发冲突。代码如下所示:

#include 
namespace ns {
    int var = 0;
    void fun (void){
        int a = 10;
        std::cout << "a = " << a << std::endl;
    }
}
namespace ns1 {
    int var = 0;
}
using namespace ns;
using namespace ns1;
int main(int argc, const char * argv[])
{
    
    std::cout << "ns::var = " << var << std::endl;
    fun();
    return 0;
}
上述代码中,以下代码:
using namespace ns;
using namespace ns1;

指定ns名字空间和ns1名字空间中的所有成员,在该行语句以下的所有语句中均可直接使用。这样就导致以下语句:

 
  1. std::cout << "ns::var = " << var << std::endl;

中的变量var无法确定是ns中的还是ns1中的,而引发冲突。此时只能在变量前添加作用域限定符,代码如下:

std::cout << "ns::var = " << ns::var << std::endl;
或
std::cout << "ns::var = " << ns1::var << std::endl;

1.3 完整代码

本案例中的完整代码如下所示:

#include 
namespace ns {
    int var = 0;
    void fun (void){
        int a = 10;
        std::cout << "a = " << a << std::endl;
    }
}
namespace ns1 {
    int var = 100;
}
using namespace ns;
using namespace ns1;
int main(int argc, const char * argv[])
{
    
    //std::cout << "ns::var = " << var << std::endl;
    std::cout << "ns::var = " << ns::var << std::endl;
    std::cout << "ns1::var = " << ns1::var << std::endl;
    fun();
    return 0;
}

2 名字空间声明

2.1 问题

名字空间声明表示在当前作用域中对某个名字空间的指定成员可见,而外层作用域的同名实体将被隐藏。

2.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:使用名字空间声明

代码如下所示:

#include 
namespace ns {
    int var = 0;
    void fun (void){
        int a = 10;
        std::cout << "a = " << a << std::endl;
    }
}
using ns::var;
int main(int argc, const char * argv[])
{
    
    std::cout << "ns::var = " << var << std::endl;
    fun();
    return 0;
}

上述代码中,以下代码:

using ns::var;

指定ns名字空间中的变量成员var,在该行语句以下的所有语句中均可直接使用。

上述代码中,以下代码:

std::cout << "ns::var = " << var << std::endl;

变量var是ns名字空间中的变量,由于使用了名字空间声明,所以可以直接使用,其前面无需添加作用域限定符ns::。

上述代码中,以下代码:

fun();

由于没有使用名字空间声明,所以报错,不能使用。

步骤二:使用名字空间声明引发的冲突

代码如下所示:

#include 
namespace ns {
    int var = 0;
    void fun (void){
        int a = 10;
        std::cout << "a = " << a << std::endl;
    }
}
namespace ns1 {
    int var = 0;
}
using ns::var;
using ns1::var;

上述代码中,以下代码:

using ns::var;
using ns1::var;

由于第一行使用名字空间声明已经在当前作用域内声明了变量var,所以第二行试图再在当前作用域内声明另一个名字空间的同名变量时将报错。

2.3 完整代码

本案例中的完整代码如下所示:

#include 
namespace ns {
    int var = 0;
    void fun (void){
        int a = 10;
        std::cout << "a = " << a << std::endl;
    }
}
namespace ns1 {
    int var = 0;
}
using ns::var;
using ns1::var;
int main(int argc, const char * argv[])
{
    
    std::cout << "ns::var = " << var << std::endl;
    ns::fun();
    return 0;
}

3 名字空间声明与指令的区别

3.1 问题

名字空间声明将所声明的标识符引入当前作用域,就如同该标识符在当前作用域中被声明一样,是针对名字空间中的某个成员而言的。

名字空间指令只是将该名字空间指定为可见,并不对作用域构成任何影响,是针对名字空间中的所有成员而言的。

3.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:名字空间声明与指令的区别

代码如下所示:

#include 
namespace ns {
    int var = 10;
    void fun (void){
        int a = 10;
        std::cout << "a = " << a << std::endl;
    }
}
namespace ns1 {
    int var = 0;
}
using ns::fun;
using namespace ns1;

上述代码中,以下代码:

using ns::fun;

是名字空间声明,其作用仅是使名字空间ns中的fun函数成员在当前作用域有效。

上述代码中,以下代码:

using namespace ns1;

是名字空间指令,其作用是使名字空间ns1中的所有成员在当前作用域有效。

3.3 完整代码

本案例中的完整代码如下所示:

#include 
namespace ns {
    int var = 10;
    void fun (void){
        int a = 10;
        std::cout << "a = " << a << std::endl;
    }
}
namespace ns1 {
    int var = 0;
}
using ns::fun;
using namespace ns1;
int main(int argc, const char * argv[])
{
    
    std::cout << "ns::var = " << var << std::endl;
    fun();
    return 0;
}

4 无名名字空间

4.1 问题

无名名字空间,又称为全局名字空间,不属于任何有名名字空间的标识符,都隶属于无名命名空间。全局作用域中定义的标识符被隐式地添加到无名名字空间中。

4.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:在无名名字空间中定义成员

代码如下所示:

#include 
int var = 100;
int main(int argc, const char * argv[])
{
    
    std::cout << "var = " << var << std::endl;
    return 0;
}

上述代码中,全局变量var就定义在无名名字空间中。

步骤二:使用无名名字空间中成员的冲突

代码如下所示:

#include 
namespace ns {
    int var = 10;
    void fun (void){
        int a = 10;
        std::cout << "a = " << a << std::endl;
    }
}
int var = 100;
int main(int argc, const char * argv[])
{
    
    int var = 200;
    std::cout << "var = " << var << std::endl;
    std::cout << "::var = " << ::var << std::endl;
    std::cout << "ns::var = " << ns::var << std::endl;
    
    return 0;
}

上述代码中,以下代码:

std::cout << "var = " << var << std::endl;

变量var为局部变量,因为局部变量会隐藏全局变量,此时如果想要使用全局变量,需要在变量var前加作用域限定符::。

代码如下所示:

std::cout << "::var = " << ::var << std::endl;

4.3 完整代码

本案例中的完整代码如下所示:

#include 
namespace ns {
    int var = 10;
    void fun (void){
        int a = 10;
        std::cout << "a = " << a << std::endl;
    }
}
int var = 100;
int main(int argc, const char * argv[])
{
    
    int var = 200;
    std::cout << "var = " << var << std::endl;
    std::cout << "::var = " << ::var << std::endl;
    std::cout << "ns::var = " << ns::var << std::endl;
    
    return 0;
}

5 多层名字空间

5.1 问题

多层名字空间,又称为名字空间的嵌套,是指定义在其他名字空中的名字空间。

5.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:定义多层名字空间

代码如下所示:

#include 
namespace ns1 {
    int var = 10;
    namespace ns2 {
        int var = 20;
        void fun (void){
            std::cout << "ns2::var = " << var << std::endl;
        }
    }
}
int main(int argc, const char * argv[])
{
    
    std::cout << "ns1::var = " << ns1::var << std::endl;
    ns1::ns2::fun();
    
    return 0;
}

上述代码中,以下代码:

 void fun (void){
    std::cout << "ns2::var = " << var << std::endl;
 }

中的变量var是名字空间ns2中的整型变量成员var,因为内层空间中的同名成员会隐藏外层空间中的同名成员。

上述代码中,以下代码:

ns1::ns2::fun();

对于内层名字空间中的成员的引用,需要通过作用域限定操作符逐层的分解。

5.3 完整代码

本案例中的完整代码如下所示:

#include 
namespace ns1 {
    int var = 10;
    namespace ns2 {
        int var = 20;
        void fun (void){
            std::cout << "ns2::var = " << var << std::endl;
        }
    }
}
int main(int argc, const char * argv[])
{
    
    std::cout << "ns1::var = " << ns1::var << std::endl;
    ns1::ns2::fun();
    
    return 0;
}

 

你可能感兴趣的:(C语言/C++)