0. 前言
这些内容同时也是为之后学习C++类和对象打基础, 下面说一下C++是如何优化C语言中的作用域
1. 命名空间
在说明命名空间的概念和如何优化C作用域之前, 首先来看一个例子
如图, 编译器报rand重定义错误, 发生这个错误的原因是<stdlib.h>头文件中有一个名为rand的函数
当它包含进t1.cpp源文件后, 它与变量rand发生命名冲突,如下图
这个命名冲突在C语言中是没有办法解决的,因为在C语言中只有局部和全局作用域的概念
而在局部作用域中创建的变量出了作用域后就会被销毁, 所以也不能解决问题
#include <stdio.h>
#include <stdlib.h>
void test()
{
int rand = 0;
} // 变量rand销毁
int main()
{
printf("%d ", rand);
}
但是命名冲突在C++中可以用命名空间来解决
1.1 命名空间的概念
命名空间可以理解为一个域,这个域叫做命名空间域, 命名空间域与其他不同的域分离, 以此解决命名冲突的问题, 如下图
此时变量rand在命名空间域中, 此时它与函数名rand在不同的域中,不同的域可以有相同的名字,所以这样就解决了命名冲突
下面用实际代码证明
#include <stdio.h>
#include <stdlib.h>
// 命名空间的定义
namespace test
{
int rand = 0;
}
int main()
{
printf("%dn", test::rand); // 命名空间的使用
}
如图所示, 打印出了变量rand的值, 解决了命名冲突 ,接下来详细说一下命名空间的定义与使用
1.2 命名空间的定义
1. 命名空间定义的语法:
关键字namespace+命名空间名字+{}
namespace test
{
int rand = 0;
}
2. 命名空间定义的规则:
- 命名空间内部可以定义变量, 函数和结构
namespace test1
{
// 命名空间内可以定义变量, 函数和结构
int rand = 0;
int add(int x, int y)
{
return x + y;
}
struct SLNode
{
int data;
struct SLNode* next;
};
}
- 命名空间可以嵌套命名空间
namespace test1
{
int rand = 0;
// 命名空间可以嵌套命名空间
namespace test2
{
int a = 1;
int sub(int x, int y)
{
return x - y;
}
}
}
1.3 命名空间的使用
命名空间有三种使用方式
1. 指定命名空间域:
#include <stdio.h>
namespace test1
{
int a = 0;
int c = 2;
namespace test2
{
int b = 1;
}
}
int main()
{
// 1. 指定命名空间域 --- 命名空间名字 + 作用域限定符 + 命名空间成员
printf("%dn", test1::a);
printf("%dn", test1::test2::b);
}
2. 使用using将命名空间中某个成员引入
#include <stdio.h>
namespace test1
{
int a = 0;
int c = 2;
namespace test2
{
int b = 1;
}
}
// 2. 使用using将命名空间中某个成员引入
using test1::a;
using test1::test2::b;
int main()
{
printf("%dn", a);
printf("%dn", b);
return 0;
}
3. 使用using namespace 命名空间名引入
#include <stdio.h>
namespace test1
{
int a = 0;
int c = 2;
namespace test2
{
int b = 1;
}
}
// 3. 使用using namespace 命名空间名引入
using namespace test1;
int main()
{
printf("%dn", a);
return 0;
}
1.4 三种命名空间使用的含义
上面说明了三种命名空间的使用,下面来具体说一下它们各自的含义还有与包含头文件的区别
using 引入:
using namespace 引入:
包含头文件是将头文件中的函数声明拷贝到源文件中, 所以使用命名空间和包含头文件是两个不同的概念
1.5 关于命名空间的思考
1. 命名空间域默认是关闭的, 只有如上的3种方法使用命名空间域
2. 所有的C++头文件和STL都封在一个名为std命名空间域中
如图所示, 只有将命名空间域std引入, 才能使用iostream头文件, 这样是为了防止C++标准库与我们自己写的代码之间出现命名冲突
文章来源: 博客园
- 还没有人评论,欢迎说说您的想法!