"使用命名空间std; "在C++中是不好的做法

C++是一种非常常用的编程语言,它被许多活跃在"竞争性编程 "的用户所使用,如果他们想学习"数据结构和算法 "**的概念,并想在技术面试中掌握他们的梦想工作。

由于C++语言现在被广泛使用,但在编写其代码时,你必须包括一些头文件和一行**"using namespace std;".但你知道在C++代码或程序中包括这一行是不被认为是一个好做法吗?让我们来看看为什么以及这一行的坏处。

C++包含一个标准库,其中包括你在构建应用程序时使用的常见功能,如容器、算法、数据结构等。如果这些功能所使用的名字是公开的,例如,如果他们定义了一个随机的类,假设他们在全球范围内定义了一个 "堆栈 "类,你将永远无法再次使用相同的名字而不发生冲突。所以他们创建了一个 "命名空间,std "来包含这一变化。using namespace "语句或行只是意味着在它出现的特定范围内,使 "std namespace "下的所有东西都可用,而不必在每个东西之前使用前缀 "std::"。将整个 "std namespace "拉入全局命名空间是不好的,因为它违背了命名空间的目的,可能导致名称冲突。这种情况被称为**"命名空间污染"。

语句"using namespace std;"通常被认为是不好的做法。这个声明的替代方法是,在我们每次声明一个类型时,使用范围操作符(::)指定标识符所属的名字空间。虽然该语句使我们在访问定义在std命名空间的类或类型时不用输入std::,但它将整个std命名空间导入到程序的当前命名空间。让我们看看一些例子,看看为什么使用这一行被认为不是一个好的做法。

现在,如果有人想在C++中使用来自std命名空间的输出函数 "cout",那么代码会是怎样的呢?**"//"**这意味着在我们的代码中添加注释,因为它使代码更易读,更有效地让别人理解:

//first we include relevant header files
#include <iostream> 
using namespace std; //this is the line we have to use in our code to execute it
cout<<"HELLO!"; //this will print hello in the output terminal
复制代码

例如,在一段时间后,我们希望使用另一个样本或版本的cout,它是在另一个库中实现的,假设我们称它为 "hello.h".我们也必须包含那个头文件或库。看完这个例子,你会清楚地明白:

//include header files
# include <hello.h>
# include <iostream>
using namespace std;
cout<<"HELLO!";
复制代码

现在你已经注意到,存在着一种矛盾或不确定性,cout指向哪个库?编译器可能会检测到这一点,从而无法编译该程序或给定的代码。在最坏的情况下,程序仍然可以编译,但会调用错误的函数,因为我们没有指定标识符属于哪个命名空间。所以现在你们都对"为什么使用命名空间std;"被认为是一种不好的做法有了一点清楚的认识。现在让我们进一步看看。

命名空间被引入到C++中,以解决标识符名称问题、问题或冲突。这确保了两个对象可以有相同的名字,但却被以不同的方式对待,就好像它们属于不同的命名空间。你一定已经观察到并注意到在上面解释的例子中发生了完全相反的情况。
当我们包括或导入一个命名空间时,我们基本上是把所有类型的定义拉到当前的范围内。std 命名空间是非常大的,而且很大。它有数以百计的预定义标识符,所以开发者或用户很有可能会忽略或无视这样一个事实,即在std库中还有一个他们想要的对象的定义。由于没有意识到这一点,他们可能会继续指定他们自己的实现,并期望它在程序的后面部分被使用。因此,在当前命名空间中,同一类型会有两个定义。这在C++中是不允许的,即使程序被编译或执行,也无法知道哪个定义被用在哪里。这个问题的解决方案是使用范围操作符":: "明确指定我们的标识符属于哪个命名空间。 现在让我们看一个如何使用这个特殊的操作符来解决这个问题的例子:

//include header files
#include <hello>
#include <iostream>
std::cout<<"Something to display"; // Using cout of std library
hello::cout<<"Something to display"; // Using cout of hello library
复制代码

但是,每次我们定义一个类型时都要输入 "std:: "是很单调的。这也使得我们的代码看起来非常低效,而且冗长,有很多的类型定义,让读者很难判断或阅读代码。被复杂、繁琐、冗长的类型定义搞得一团糟的源代码是非常难读的。这是开发人员或用户力图避免或忽略的,因为代码的可维护性是一个非常重要的因素,他们对这件事考虑得非常敏锐。有一些方法可以解决这个困境或问题,通过指定准确的命名空间,而不需要用std关键字搞乱代码。现在我们将介绍一些方法,通过这些方法我们可以轻松解决这个问题。

  1. 使用 "类型定义":类型定义可以很容易地解决这个问题,因为它们可以使我们免于编写长的类型定义。现在请看下面提到的例子,它只是对之前使用的例子的修改,我们使用了两个库:
//include header files
#include <hello>
#include <iostream>
typedef std::cout cout_std;
typedef hello::cout cout_hello;
cout_std<<"HELLO!";
cout_hello<<"HELLO!";
复制代码

现在看到这个例子,我们可以观察到,现在的程序看起来有点可理解了。

  1. "尝试在有限的范围内而不是在全局范围内导入命名空间":如果我们在函数内或有限的范围内导入命名空间,命名空间的定义就会被导入到一个局部范围内,我们至少知道如果出现错误,可能会在哪里发生。看完这个例子的代码,你就会明白了:
//include header files
#include <iostream>
void hello()
{
    using namespace std; //use inside any function
    // Now proceed with function
}
复制代码

通过OpenGenus的这篇文章,我相信你们都清楚地知道为什么在代码中使用命名空间std;不是一个好的做法。在开发代码或任何应用程序时,开发人员有必要了解他们的代码中可能出现的所有问题,并知道解决这些问题的方法,这样他们的代码就会变得简单、高效、明确、可读和没有错误。

扫描二维码关注公众号,回复: 14416053 查看本文章

猜你喜欢

转载自juejin.im/post/7125727586378285086