什么是命名空间,为什么有必要

cod*_*guy 10 c++ namespaces std

我现在正在学习C++,在每个项目的开始阶段,我的讲师都会说:

using namespace std;
Run Code Online (Sandbox Code Playgroud)

据我所知,它使您不必调用包含头名称的头文件中的函数,如iostream :: stdout,而只需调用stdout.

但这条线究竟告诉C++做什么.什么是命名空间,什么是std?

除了python之外,我也是编程新手,所以切换到一个新的范例对我来说非常困惑.

Ale*_*íaz 13

来自cppreference.com:

命名空间提供了一种防止大型项目中名称冲突的方法.

在命名空间块内声明的符号放在命名范围内,以防止它们被误认为其他范围内具有相同名称的符号.

允许使用具有相同名称的多个名称空间块.这些块中的所有声明都在命名范围内声明.

命名空间可以避免名称冲突,例如标准库定义,sort()但这对于排序函数来说是一个非常好的名称,这要归功于您可以定义自己的命名空间,sort()因为它不会与标准命名空间位于同一名称空间中.

using指令告诉编译器在当前作用域中使用该命名空间,这样就可以了

int f(){
    std::cout << "out!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

要么:

int f(){
    using namespace std;
    cout << "out!" << endl;
}
Run Code Online (Sandbox Code Playgroud)

当你从另一个命名空间中使用很多东西时,它很方便.

source:Namespaces - cppreference.com


小智 5

我们先从一个问题来解释一下什么是命名空间。我们都知道函数、类或任何其他类型的数据不能具有相同的名称。假设我们有两个库都添加了一个函数,比如说 print()。它们都具有不同的功能,但在命名上它们是无法区分的。这就是命名空间的用武之地。命名空间就像添加一个新的组名称,您可以在其中添加函数和其他数据,以便它变得可区分。

namespace bla
{
  void print()
  {
    // function bla::print()
  }
}

namespace blabla
{
  void print()
  {
    // function blabla::print()
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,如您所见,有两个名为 print 的函数,但由于名称空间的原因,不存在命名冲突。第一个函数将使用 bla::print() 调用,第二个函数将使用 blabla::print() 调用。

std是标准的缩写。std 是标准命名空间。cout、cin 和很多其他的东西都在里面定义了。(这意味着调用它们的一种方法是使用 std::cout 和 std::cin。)

关键字 using 从技术上讲意味着尽可能使用它。在本例中,它指的是 std 命名空间。因此,每当计算机遇到 cout、cin、endl 或任何类似内容时,它都会将其读取为 std::cout、std::cin 或 std::endl。

当您不使用 std 命名空间时,计算机将尝试调用 cout 或 cin,就好像它没有在命名空间中定义一样(与代码中的大多数函数一样)。由于它不存在,计算机会尝试调用不存在的东西!因此,出现错误。


278*_*528 5

但这条线究竟告诉C++做什么.什么是命名空间,什么是std?

std是一个命名空间.

命名空间是符号的集合.

该行告诉您的C++编译器

a)搜索命名空间std(即iostream,iomanip)的包含部分if

b)之前没有找到符号的定义(例如(std::) cout)

c)声明符号未知.

命名冲突解决(正如其他答案所述)可能是解决的最重要问题.

我最喜欢的命名空间是命名空间内容(类和函数)可以添加到多个头文件中.(与类相比,它必须完全在一个头文件中).

因此,iostream,iomanip,string,stringstream各自独立地为std命名空间贡献类和代码.

因此,我可以将大多数工具保存在单独的文件中,然后将它们"逻辑地"合并到一个命名空间中.

例如:我有一个基于ram的固定大小的日志文件dtb_log.hh,简要的大纲如下所示:

// Name:        dtb_log.hh
//
#ifndef DTB_LOG_HH
#define DTB_LOG_HH

namespace DTB  // <acronym description>
{    
   class Log
   {
   public:
       // ...

   }; // class Log

} // namespace DTB 

#endif // DTB_LOG_HH
Run Code Online (Sandbox Code Playgroud)

我在文件dtb_mem_tag.hh中也有一个(很少使用,在这种情况下相关)实用程序

// Name:         dtb_mem_tag.hh
//
#ifndef DTB_MEM_TAG_HH
#define DTB_MEM_TAG_HH


namespace DTB    // <acronym name def>
{
   class MemTag
   {
   public:
   // ...
   };  // class MemTag

} // namespace DTB    

#endif // DTB_MEM_TAG_HH
Run Code Online (Sandbox Code Playgroud)

使用DTB :: MemTag和DTB :: Log就像包含各自的#include头文件一样简单.

在使用它们的应用程序中,每个用法都可以用'DTB ::'前缀清楚地标记.


需要工作的任何DTB代码'evolution'都在我的'dtb'命名空间目录中.

因此,仅通过文件日期戳我可以告诉ubuntu 64的过渡对我的工具有何影响.例如,我可以看到dtb_termselect.xx(用于arduino交互代码)已经更新,就像dtb_popen.xx,dtb_pause和其他几个一样.


在团队环境中(前一段时间),我们讨论了共享命名空间的各种方法.一般来说,这并不是很受欢迎......太难以达成一致意见.

但在讨论的想法中,使用命名空间作为贡献作者的签名的想法.因此创建了DTB(我的)和KTS(肯的过渡服务),以及其他一些.不是每个人都对此感到兴奋.