命名空间到底是什么,为什么有必要
What exactly is a namespace and why is it necessary
我现在正在学习 C++,在每个项目的开始,我的导师都会写一行:
using namespace std;
我知道它可以让您不必调用 header 中的函数,您将它们的 header 名称包含在 iostream::stdout 中,而只是调用 stdout。
但这行代码究竟告诉 C++ 做什么。什么是命名空间,什么是标准?
除了python之外,我也是编程新手,所以切换到新的范式对我来说非常困惑。
来自 cppreference.com:
Namespaces provide a method for preventing name conflicts in large
projects.
Symbols declared inside a namespace block are placed in a named scope
that prevents them from being mistaken for identically-named symbols
in other scopes.
Multiple namespace blocks with the same name are allowed. All
declarations within those blocks are declared in the named scope.
命名空间可以避免名称冲突,例如标准库定义了 sort()
但对于排序函数来说这是一个非常好的名称,感谢命名空间,您可以定义自己的 sort()
因为它不会与标准名称空间在同一个名称空间中。
using 指令告诉编译器在当前范围内使用该命名空间,因此您可以
int f(){
std::cout << "out!" << std::endl;
}
或:
int f(){
using namespace std;
cout << "out!" << endl;
}
当您使用来自另一个命名空间的大量内容时,它会很方便。
我们先从一个问题说起什么是命名空间。我们都知道我们不能有函数、类 或任何其他类型的同名数据。假设我们有两个库都添加了一个函数,比如说 print()。它们都赋予不同的功能,但在命名上它们是无法区分的。这就是命名空间的用武之地。命名空间就像添加一个新的组名,您可以在其中添加函数和其他数据,以便它变得可区分。
namespace bla
{
void print()
{
// function bla::print()
}
}
namespace blabla
{
void print()
{
// function blabla::print()
}
}
现在,如您所见,有两个名为 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,就好像它们未在命名空间中定义一样(就像代码中的大多数函数一样)。因为那里不存在,所以计算机会尝试调用不存在的东西!因此,发生错误。
But what exactly does the line tell C++ to do. What is a namespace and
what is std?
std 是一个命名空间。
命名空间是符号的集合。
该行告诉您的 C++ 编译器
a) 搜索命名空间 std 的包含部分(即 iostream、iomanip)if
b) 在
之前没有找到符号的定义(例如 (std::) cout )
c) 声明符号未知。
命名冲突解决(如其他答案所述)可能是解决的最重要的问题。
我最喜欢命名空间的一点是命名空间内容(classes 和函数)可以跨多个头文件添加。 (与必须完全在一个头文件中的 class 相反)。
因此,iostream、iomanip、string、stringstream 各自独立地向 std 命名空间提供 classes 和代码。
因此我可以将大部分工具保存在单独的文件中,然后将它们 'logically' 合并到一个命名空间中。
例如:我有一个基于 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
我在文件 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
同时使用 DTB::MemTag 和 DTB::Log 就像包含各自的 #include 头文件一样简单。
并且在使用这些的应用程序中,可以使用 'DTB::' 前缀清楚地标记其中任何一个的用法。
任何需要工作的 DTB 代码 'evolution' 都在我的 'dtb' 命名空间目录中。
因此,仅通过文件日期戳,我就可以判断向 ubuntu64 的过渡对我的工具产生了哪些影响。例如,我可以看到 dtb_termselect.xx(用于 arduino 交互代码)已更新,dtb_popen.xx、dtb_pause 和其他几个也已更新。
在团队环境中(不久前),我们讨论了共享命名空间的各种方式。总的来说,这不是很受欢迎......太难同意了。
但在讨论的想法中,有一个想法是使用名称空间作为贡献作者的签名。因此创建了 DTB(我的)和 KTS(Ken 的过渡服务),以及其他一些。也不是每个人都热衷于此。
我现在正在学习 C++,在每个项目的开始,我的导师都会写一行:
using namespace std;
我知道它可以让您不必调用 header 中的函数,您将它们的 header 名称包含在 iostream::stdout 中,而只是调用 stdout。
但这行代码究竟告诉 C++ 做什么。什么是命名空间,什么是标准?
除了python之外,我也是编程新手,所以切换到新的范式对我来说非常困惑。
来自 cppreference.com:
Namespaces provide a method for preventing name conflicts in large projects.
Symbols declared inside a namespace block are placed in a named scope that prevents them from being mistaken for identically-named symbols in other scopes.
Multiple namespace blocks with the same name are allowed. All declarations within those blocks are declared in the named scope.
命名空间可以避免名称冲突,例如标准库定义了 sort()
但对于排序函数来说这是一个非常好的名称,感谢命名空间,您可以定义自己的 sort()
因为它不会与标准名称空间在同一个名称空间中。
using 指令告诉编译器在当前范围内使用该命名空间,因此您可以
int f(){
std::cout << "out!" << std::endl;
}
或:
int f(){
using namespace std;
cout << "out!" << endl;
}
当您使用来自另一个命名空间的大量内容时,它会很方便。
我们先从一个问题说起什么是命名空间。我们都知道我们不能有函数、类 或任何其他类型的同名数据。假设我们有两个库都添加了一个函数,比如说 print()。它们都赋予不同的功能,但在命名上它们是无法区分的。这就是命名空间的用武之地。命名空间就像添加一个新的组名,您可以在其中添加函数和其他数据,以便它变得可区分。
namespace bla
{
void print()
{
// function bla::print()
}
}
namespace blabla
{
void print()
{
// function blabla::print()
}
}
现在,如您所见,有两个名为 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,就好像它们未在命名空间中定义一样(就像代码中的大多数函数一样)。因为那里不存在,所以计算机会尝试调用不存在的东西!因此,发生错误。
But what exactly does the line tell C++ to do. What is a namespace and what is std?
std 是一个命名空间。
命名空间是符号的集合。
该行告诉您的 C++ 编译器
a) 搜索命名空间 std 的包含部分(即 iostream、iomanip)if
b) 在
之前没有找到符号的定义(例如 (std::) cout )c) 声明符号未知。
命名冲突解决(如其他答案所述)可能是解决的最重要的问题。
我最喜欢命名空间的一点是命名空间内容(classes 和函数)可以跨多个头文件添加。 (与必须完全在一个头文件中的 class 相反)。
因此,iostream、iomanip、string、stringstream 各自独立地向 std 命名空间提供 classes 和代码。
因此我可以将大部分工具保存在单独的文件中,然后将它们 'logically' 合并到一个命名空间中。
例如:我有一个基于 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
我在文件 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
同时使用 DTB::MemTag 和 DTB::Log 就像包含各自的 #include 头文件一样简单。
并且在使用这些的应用程序中,可以使用 'DTB::' 前缀清楚地标记其中任何一个的用法。
任何需要工作的 DTB 代码 'evolution' 都在我的 'dtb' 命名空间目录中。
因此,仅通过文件日期戳,我就可以判断向 ubuntu64 的过渡对我的工具产生了哪些影响。例如,我可以看到 dtb_termselect.xx(用于 arduino 交互代码)已更新,dtb_popen.xx、dtb_pause 和其他几个也已更新。
在团队环境中(不久前),我们讨论了共享命名空间的各种方式。总的来说,这不是很受欢迎......太难同意了。
但在讨论的想法中,有一个想法是使用名称空间作为贡献作者的签名。因此创建了 DTB(我的)和 KTS(Ken 的过渡服务),以及其他一些。也不是每个人都热衷于此。