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

时间:2010-11-06 18:16:43

标签: c++

在C#中,只使用using指令作为命名空间。在下面这个例子中的C ++中,必须要做一个include然后使用命名空间,为什么它不像C#中的那样?

#include <iostream>

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

6 个答案:

答案 0 :(得分:7)

因为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;。在C#中,您调用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 {

答案 1 :(得分:2)

我通常不会回答有这么多有用答案的问题,但似乎没有人注意到你的问题中的“导入”。在C和C ++中,“#include”指令与Java中的“import”或C#中的“using”相同。从字面上看,#include指令只是添加了包含该指令的文件的编译行。周期。

在大多数其他编译器语言中,没有与#include类似的功能;但几乎每个有用的汇编程序都有这样的功能。 C是一种低级语言,最初设计用于便携式实现操作系统内核,驱动程序和实用程序。 C ++是一种更高级的语言,但建立在C语言之上。一个深思熟虑的设计目标是允许大多数C程序在没有源代码更改的情况下进行编译,作为合法的C ++程序。

在学习C ++时,请牢记这一点。它可以帮助您理解为什么它如何以它的方式组合在一起。

C ++标准库比Java或C#的框架小得多,并且所有这些都是在std命名空间中定义的。这意味着整个库所需的唯一“导入”是“using namespace std;”,这就是在没有显式std ::前缀的情况下将这些名称带入视图的内容;但只有那些已经#included进入当前编辑的名称。

答案 2 :(得分:1)

如果不使用include,那么就编译器而言,该头中声明的内容不存在。为了使用函数,编译器必须知道它存在。 using指令和#include是完全切向的 - 你根本不需要使用,许多经验丰富的程序员都会推荐使用它。

答案 3 :(得分:1)

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

另一方面,使用direcive完全与C#中的那个完全相同。

答案 4 :(得分:1)

使用命名空间std的目的; line是这样你不必每次都输入完整的std :: cout,std :: endl。当您使用标准库中的cout,endl或任何其他函数而没有使用标准库中的标准库的std ::时,它将假设。

您可以自己尝试,使用命名空间std删除;并尝试编译。你应该得到错误。然后尝试使用std :: cout&lt;&lt; “你好,世界!” &LT;&LT;的std :: ENDL;它会像以前一样工作。

在这里查看:

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

答案 5 :(得分:1)

它实际上与C#类似。使用确实只用于命名空间,即使在C#中尝试使用未引用的程序集中的某些内容,无论您说using Foo.Bar多少次都无法使用它。添加引用类似于C ++中的include步骤(尽管不完全相同,C#使“包括”和“链接”一步)。