繁体   English   中英

为什么在C ++中已经使用了import指令后需要使用命名空间?

[英]Why in C++ do I need to use namespace after already using import directive?

在C#中,仅将using指令用于名称空间。 在C ++中,如下面的示例所示,必须先进行包含然后使用名称空间,为什么它不像C#中一样?

#include <iostream>

int main()
{
   using namespace std;
   cout << "Hello world!" << endl;
   return 0;
}

因为C#中的编译器的工作原理与C ++完全不同。

快速版本-C#使用引用的方式(某种程度上)类似于C ++使用链接器和转发声明。 C ++需要前向声明,因此它可以将每个源文件编译为翻译单元, 然后将所有这些单元链接在一起。 C#编译器为您引用的程序集加载代码,然后立即编译整个程序集,因此不需要这些前向声明。

长版-

C ++

在C ++中,如果要使用代码,则必须将其添加到链接器中,并提供前向声明。 头文件包含前向声明,并且包含文件只需将该文件复制/粘贴到源文件中即可。

这是因为C ++具有称为翻译单元的中间步骤,并且会生成目标文件。 链接器将它们粘合在一起。

在您的示例中, #include <iostream>提供了前向声明,并通过包含头文件(以前称为“ iostream.h”,但现在称为“ iostream”)来实现。 该头文件将被复制/粘贴到您的源代码中(连同该文件包含的所有头等等)。 所有这些都被编译成一个翻译单元(目标文件),并链接到C ++运行时(可能还有C运行时,也许还有其他运行时),并变成可执行文件。

C#

在C#中,如果要使用代码,则可以添加对项目或构建文件的引用,或者只是将C#文件添加到同一项目。 不需要任何前向声明,但是您必须引用该代码,或者在当前程序集中包含该代码的另一个源文件。

C#没有中间翻译单元。 它仅产生装配体。

当您引用System.dll时,您已经有了可用的代码。 您不必提供前向声明,因此不需要包括任何标头。

您可以使用using关键字将整个名称空间拉入当前作用域。 在C ++中,您using namespace std;调用using namespace std; 在C#中,您using System;调用using System;

然后,您可以执行以下操作:

std::cout << "test1\n";
cout << "test2\n";

要么

System.Console.WriteLine("test1");
Console.WriteLine("test1");

我忘记了是否可以使用C ++,但是在C#中,您还可以使用别名命名空间:

using Ser = System.Runtime.Serialization;

...

class Blah : Ser.ISerializable {

或别名类型:

using ISer = System.Runtime.Serialization.ISerializable;

...

class Blee : ISer {

我通常不会用这么多有用的答案回答问题,但是似乎没有人注意到您的问题中的“导入”。 在C和C ++中,“#包括”指令是一样的,如C#在Java中“进口”或“使用”。 从字面上看,#include指令只是向您添加包含该指令的文件的编译行。 期。

在大多数其他编译器语言中,没有与#include具有可比性的功能; 但是几乎每个有用的汇编程序都具有这样的功能。 C是一种最初设计用于操作系统内核,驱动程序和实用程序的可移植实现的低级语言。 C ++是一种高级语言,但基于C语言。一个有意的设计目标是允许大多数C程序像合法C ++程序一样在没有源代码更改的情况下进行编译。

在学习C ++时,请牢记这张图。 它可以帮助您了解为什么将其按原样组合在一起。

C ++标准库比Java或C#框架要小得多,所有这些都在std名称空间中定义。 这意味着整个库唯一需要的“导入”是“使用命名空间std;”,这使那些名称无需显式std ::前缀即可显示。 但是只有那些已经#include到当前编译中的名称。

如果不使用include,那么就编译器而言,该标头中声明的内容都不存在。 为了使用函数,编译器必须知道它的存在。 using指令和#include完全是切线的-您完全不必使用using,许多更有经验的程序员建议不要使用它。

include指令只是将源文件复制粘贴到程序中,仅此而已(例如,在代码中,#include将C ++编译器中安装的源文件“ iostream”放入源代码中。

另一方面,使用直接执行功能与C#中的功能完全相同。

使用命名空间std的目的; 行是这样,因此您不必每次都键入完整的std :: cout,std :: endl。 它将假设您确实在不使用std ::的情况下使用标准库中的cout,endl或任何其他函数时,要使用标准库中的那个。

您可以自己尝试,使用命名空间std删除; 并尝试编译。 您应该得到错误。 然后尝试再次使用std :: cout <<“ Hello world!”进行编译。 << std :: endl; 它会像以前一样工作。

在这里查看:

http://www.cplusplus.com/doc/tutorial/namespaces/

实际上在C#中是相似的。 使用确实仅适用于命名空间,即使在C#中,也可以尝试使用未引用的程序集中的某些内容,无论您using Foo.Bar了多少次using Foo.Bar ,都无法using Foo.Bar 添加引用类似于C ++中的include步骤(尽管不完全相同,但C#使“ include ”和“ linking”成为单个步骤)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM