C++ 之命名空间namespace【详解】

简介: C++ 之命名空间namespace【详解】


一,命名空间出现的意义

命名空间(Namespace)在编程中的作用主要有以下几点意义

  • 避免命名冲突:命名空间提供了一种将标识符(如变量、函数、类等)组织和隔离的方式。不同的命名空间可以拥有相同名称的标识符,避免了不同模块或库之间的命名冲突。
  • 提高可读性和可维护性:通过使用命名空间,可以更清晰地表示代码中的层次结构和组织关系。这样,其他开发者可以更容易理解代码,并且在开发或维护时可以更方便地定位和修改相关部分。
  • 模块化和组件化:命名空间可以用于划分代码逻辑上的模块和组件。每个命名空间可以包含相关的函数、类、常量等,实现了代码的模块化和组件化,使得代码更加可组织和易于扩展。
  • 提供封装和访问控制:命名空间可以用于封装代码,并提供对外部的访问控制。通过在命名空间中定义私有成员和公共接口,可以限制对命名空间内部的访问,增强代码的安全性和稳定性。
  • 支持库和框架开发:命名空间为库和框架的开发提供了一种清晰的组织结构。不同的模块可以通过命名空间进行逻辑上的分割和集成,使得库和框架更易于使用和扩展。
      总的来说,命名空间提供了一种组织、隔离和管理代码的机制,有助于避免命名冲突、提高可读性和可维护性,以及支持模块化和封装。它在大型项目或多人协作开发中尤为重要,能够提高代码的可靠性和可扩展性。

  最重要的一点还是命名冲突,下面举个例子能够直观的感受:

#include<stdlib.h>
#include <stdio.h>
int rand = 9;
int main()
{
  printf("%d", rand);
  
  return 0;
}

运行以后,这段代码会出现这样的错误:

因为在头文件stdlib.h里面定义了rand,然后我们又自定义了一个rand,就会出现重定义这个现象

  这个问题的危害就是在公司做大型项目的时候,每个人都会定义很多变量,当整合在一起的时候,就会出现很多的重定义现象,这个问题在C语言里面是无解的,只能一方去妥协。在C++里面就解决了这个问题,引入了命名空间

二,命名空间的定义

  命名空间的定义需要用到namespace关键字,后面跟上一对**{}**,{}里面包含了命名空间的成员。


命名空间里面可以包含变量,函数,类型:

namespace tanghuan
{
  int a = 10;
  int arr[10] = { 0 };
  int sum(int a, int b)
  {
    return a + b;
  }
  struct N
  {
    int i = 0;
  };
}
int main()
{
  return 0;
}

命名空间不可以定义在局部作用域:

命名空间可以嵌套:

namespace tanghuan
{
  namespace Test
  {
    int u = 9;
  }
  int a = 10;
  int arr[10] = { 0 };
  int sum(int a, int b)
  {
    return a + b;
  }
  struct N
  {
    int i = 0;
  };
}
int main()
{
  
  return 0;
}

三,同一个工程中允许存在多个相同名称的命名空间,编译器最后会将其合并成一个命名空间,不会报错:

但是不允许存在相同变量/函数/类型,否则会报错:

允许存在未命名的名称空间

#include <stdio.h>
namespace
{
  int a = 10;
  int arr[10] = { 0 };
  int sum(int a, int b)
  {
    return a + b;
  }
  struct N
  {
    int i = 0;
  };
}
int main()
{
  printf("%d ", a);
}

  这种命名空间没有名称,就不能使用using声明和using编译指令来使他在其他位置也可用,从某方面来看,他和全局变量相似,具有内部链接性,也就是不能在命名空间所属文件以外的地方使用该命名空间里面的成员。


一个命名空间的定义就相当于给其中的成员围上了栏杆,没有允许的话,任何人都不能访问其中的变量,不同命名空间里面即使是相同的变量名,但是本质是两个变量:

但是套上了不同命名空间的"牌子",编译器就能正确区别出他们啦。

四,命名空间的使用

先介绍一下:

  • :: 叫做域作用限定符。
  • using 也是属于C++的关键字。

命名空间的使用有三种方式:

用于测试的已经定义好的命名空间:

#include <stdio.h>
namespace tanghuan
{
  int a = 10;
  int arr[10] = { 0 };
  int sum(int a, int b)
  {
    return a + b;
  }
  struct N
  {
    int i = 0;
  };
}

加命名空间名称及作用域限定符

int main()
{
  printf("%d\n", tanghuan::a);
  return 0;
}

使用using将命名空间的某个成员引入(using声明)

using tanghuan::a;
int main()
{
  printf("%d", a);
  return 0;
}

使用“using namespace 命名空间名称 ”引入(using编译指令)

using namespace tanghuan;
int main()
{
  printf("%d\n", a);
  printf("%d", sum(1, 2));
  return 0;
}

注意:

  • using声明和using编译指令可以使用在全局,此时全局展开,也可在局部使用,此时仅仅在局部有用:

  • using声明和using编译指令在局部使用的时候,和其他的局部变量一样,会覆盖全局的同名函数:

五,命名空间的使用建议

  1. 使用在已经命名的名称空间中声明的变量,而不是使用外部全局变量。
  2. 使用在已经命名的名称空间中声明的变量,而不是使用静态全局变量。
  3. 不要在头文件中使用using编译指令,首先,这样做掩盖了要让那些名称可用。另外,包含头h文件的顺序可能影响程序的行为。如果非要使用编译指令using,应该将其放在所有预处理编译指令#include之后。
  4. 导入名称时,首选将其作用域解析运算符或者using声明的方法。
  5. 对于using声明,首选将其作用域解析运算符设置为局部而不是全局。
相关文章
|
1月前
|
安全 程序员 编译器
【C++】如何巧妙运用C++命名空间:初学者必备指南
【C++】如何巧妙运用C++命名空间:初学者必备指南
|
3月前
|
程序员 C++ 开发者
C++命名空间揭秘:一招解决全局冲突,让你的代码模块化战斗值飙升!
【8月更文挑战第22天】在C++中,命名空间是解决命名冲突的关键机制,它帮助开发者组织代码并提升可维护性。本文通过一个图形库开发案例,展示了如何利用命名空间避免圆形和矩形类间的命名冲突。通过定义和实现这些类,并在主函数中使用命名空间创建对象及调用方法,我们不仅解决了冲突问题,还提高了代码的模块化程度和组织结构。这为实际项目开发提供了宝贵的参考经验。
61 2
|
2月前
|
程序员 C++ 容器
C++编程基础:命名空间、输入输出与默认参数
命名空间、输入输出和函数默认参数是C++编程中的基础概念。合理地使用这些特性能够使代码更加清晰、模块化和易于管理。理解并掌握这些基础知识,对于每一个C++程序员来说都是非常重要的。通过上述介绍和示例,希望能够帮助你更好地理解和运用这些C++的基础特性。
40 0
|
3月前
|
编译器 C语言 C++
C++入门 | 命名空间、输入输出、缺省参数
C++入门 | 命名空间、输入输出、缺省参数
44 4
|
2月前
|
C语言 C++
C++(六)Namespace 命名空间
命名空间(Namespace)是为了解决大型项目中命名冲突而引入的机制。在多库集成时,不同类库可能包含同名函数或变量,导致冲突。C++通过语法形式定义了全局无名命名空间,并允许对全局函数和变量进行作用域划分。命名空间支持嵌套与合并,便于协同开发。其使用需谨慎处理同名冲突。
|
4月前
|
安全 编译器 C++
C++一分钟之-C++中的属性命名空间
【7月更文挑战第22天】C++11引入属性作为元数据,虽无内置属性命名空间,但可通过自定义属性与命名空间组合实现类似效果。例如,创建`perf`命名空间存放`slow`和`fast`属性来标记函数性能。正确使用属性需注意位置、避免重复和确保与实现一致,以提升代码可读性和编译器理解。通过模拟属性命名空间,可以更有效地管理和使用属性。
43 1
|
4月前
|
小程序 C++
【C++入门 二 】学习使用C++命名空间及其展开
【C++入门 二 】学习使用C++命名空间及其展开
|
4月前
|
C语言 C++ 开发者
C++基础知识(一:命名空间的各种使用方法)
C++在C的基础上引入了更多的元素,例如类,类的私密性要比C中的结构体更加优秀,引用,重载,命名空间,以及STL库,模板编程和更多的函数,在面向对象的编程上更加高效。C语言的优势则是更加底层,编译速度会更快,在编写内核时大多数都是C语言去写。 在C++中,命名空间(Namespace)是一种组织代码的方式,主要用于解决全局变量、函数或类的命名冲突问题。命名空间提供了一种封装机制,允许开发者将相关的类、函数、变量等放在一个逻辑上封闭的区域中,这样相同的名字在不同的命名空间中可以共存,而不会相互干扰。
|
5月前
|
Unix 编译器 C语言
【C++航海王:追寻罗杰的编程之路】关键字、命名空间、输入输出、缺省、重载汇总
【C++航海王:追寻罗杰的编程之路】关键字、命名空间、输入输出、缺省、重载汇总
27 0
|
5月前
|
编译器 C语言 C++
【C++】:C++关键字,命名空间,输入&输出,缺省参数
【C++】:C++关键字,命名空间,输入&输出,缺省参数
42 0