C++ 命名空间和包含

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/389922/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:05:43  来源:igfitidea点击:

C++ namespace and include

c++namespacesheader-files

提问by duli

Why do we need both using namespaceand includedirectives in C++ programs?

为什么我们需要在 C++ 程序中同时使用using namespaceandinclude指令?

For example,

例如,

#include <iostream>

using namespace std;

int main() {
 cout << "Hello world";
}

Why is it not enough to just have #include <iostream>or just have using namespace stdand get rid of the other?

为什么仅仅拥有#include <iostream>或仅仅拥有using namespace std并摆脱另一个是不够的?

(I am thinking of an analogy with Java, where import java.net.*will import everything from java.net, you don't need to do anything else.)

(我正在考虑与 Java 进行类比,import java.net.*从哪里导入所有内容java.net,您无需执行任何其他操作。)

采纳答案by Tim

In C++the concepts are separate. This is by design and useful.

C++概念上是分开的。这是设计使然并且很有用。

You can include things that without namespaces would be ambiguous.

您可以包含没有命名空间的内容会不明确。

With namespaces you can refer to two different classes that have the same name. Of course in that case you would not use the usingdirective or if you did you would have to specify the namespace of the other stuff in the namespace you wanted.

使用命名空间,您可以引用两个具有相同名称的不同类。当然,在这种情况下,您不会使用该using指令,或者如果您使用了,则必须在所需的名称空间中指定其他内容的名称空间。

Note also that you don't NEED the using - you can just used std::cout or whatever you need to access. You preface the items with the namespace.

另请注意,您不需要使用 - 您可以只使用 std::cout 或您需要访问的任何内容。以命名空间作为项目的开头。

回答by Johannes Schaub - litb

using directives and include preprocessor directives are two different things. The includeroughly corresponds to the CLASSPATHenvironment variable of Java, or the -cpoption of the java virtual machine.

using 指令和包含预处理器指令是两个不同的东西。的include大致对应于CLASSPATH爪哇的环境变量,或所述-cpjava虚拟机的选项。

What it does is making the types known to the compiler. Just including <string>for example will make you able to refer to std::string:

它所做的是让编译器知道类型。仅包括<string>例如将使您能够参考std::string

#include <string>
#include <iostream>

int main() {
    std::cout << std::string("hello, i'm a string");
}

Now, using directives are like importin Java. They make names visible in the scope they appear in, so you don't have to fully qualify them anymore. Like in Java, names used must be known before they can be made visible:

现在, using 指令就像import在 Java中一样。它们使名称在它们出现的范围内可见,因此您不必再完全限定它们。就像在 Java 中一样,使用的名称必须先知道,然后才能使其可见:

#include <string> // CLASSPATH, or -cp
#include <iostream>

// without import in java you would have to type java.lang.String . 
// note it happens that java has a special rule to import java.lang.* 
// automatically. but that doesn't happen for other packages 
// (java.net for example). But for simplicity, i'm just using java.lang here.
using std::string; // import java.lang.String; 
using namespace std; // import java.lang.*;

int main() {
    cout << string("hello, i'm a string");
}

It's bad practice to use a using directive in header files, because that means every other source file that happens to include it will see those names using unqualified name lookup. Unlike in Java, where you only make names visible to the package the import line appears in, In C++ it can affect the whole program, if they include that file directly or indirectly.

在头文件中使用 using 指令是不好的做法,因为这意味着碰巧包含它的每个其他源文件都会使用不合格的名称查找来查看这些名称。不像在 Java 中,你只让名称对出现导入行的包可见,在 C++ 中,如果它们直接或间接包含该文件,它会影响整个程序。

Be careful when doing it at global scope even in implementation files. Better to use them as local as possible. For namespace std, i never use that. I, and many other people, just always write std::in front of names. But if you happen to do it, do it like this:

即使在实现文件中,在全局范围内执行此操作时也要小心。最好尽可能在本地使用它们。对于命名空间 std,我从不使用它。我和许多其他人,总是写std::在名字前面。但是,如果您碰巧这样做,请这样做:

#include <string>
#include <iostream>

int main() {
    using namespace std;
    cout << string("hello, i'm a string");
}


For what namespaces are and why you need them, please read the proposal Bjarne Stroustrup gave 1993 for adding them to the upcoming C++ Standard. It's well written:

关于什么是命名空间以及为什么需要它们,请阅读 Bjarne Stroustrup 于 1993 年提出的将它们添加到即将到来的 C++ 标准的提案。写的很好:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0262.pdf

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0262.pdf

回答by Motti

In C++ #includeand using have different functions.

在 C++ 中#include和 using 有不同的功能。

#includeputs the text of the included file into your source file (actually translation unit), namespaces on the other hand are just a mechanism for having unique names so that different people can create a "foo" object.

#include将包含文件的文本放入源文件(实际上是翻译单元)中,另一方面,命名空间只是一种具有唯一名称的机制,以便不同的人可以创建“foo”对象。

This comes from C++ not having the concept of a module.

这来自 C++ 没有模块的概念。

Keep in mind that namespaces in C++ are open, that means that different files can define different parts of the same namespace (sort of like .NET's partial classes).

请记住,C++ 中的命名空间是开放的,这意味着不同的文件可以定义同一命名空间的不同部分(有点像 .NET 的部分类)。

//a.h
namespace eg {
    void foo();
}

//b.h
namespace eg {
    void bar();
}

回答by James Curran

The include is defining the existence of the functions.

include 定义函数的存在。

The using is making it easier to use them.

使用使它们更容易使用。

coutas defined in iostream is actually named "std::cout".

coutiostream 中定义的实际上名为“std::cout”。

You could avoid using the namespace by writing.

您可以通过编写来避免使用命名空间。

std::cout << "Hello World";

回答by David Thornley

As pointed out, C++ and Java are different languages, and do somewhat different things. Further, C++ is more of a 'jest grew' language, and Java more of a designed language.

正如所指出的,C++ 和 Java 是不同的语言,并且做一些不同的事情。此外,C++ 更像是一种“开玩笑的”语言,而 Java 更像是一种设计语言。

While using namespace std;isn't necessarily a bad idea, using it for all namespaces will eliminate the whole benefit. Namespaces exist so that you can write modules without regard to name clashes with other modules, and using namespace this; using namespace that;can create ambiguities.

虽然using namespace std;不一定是一个坏主意,但将它用于所有名称空间将消除整个好处。命名空间的存在使您可以编写模块而无需考虑与其他模块的名称冲突,并且using namespace this; using namespace that;可以创建歧义。

回答by Vincent Ramdhanie

These keywords are used for different purposes.

这些关键字用于不同的目的。

The using keyword makes a name from a namespace available for use in the current declarative region. Its mostly for convenience so that you do not have to use the fully qualified name all the time. This pageexplains it in some detail.

using 关键字使名称空间中的名称可用于当前声明区域。它主要是为了方便,这样您就不必一直使用完全限定名称。此页面详细解释了它。

The #include statement is a pre processor directive and it tells the preprocessor to treat the contents of a specified file as if those contents had appeared in the source program at the point where the directive appears. That is, you can think of this statement as copying the included file into the current one. The compiler then compiles the entire file as if you wrote all the code in one big file.

#include 语句是一个预处理器指令,它告诉预处理器处理指定文件的内容,就好像这些内容在指令出现的地方出现在源程序中一样。也就是说,您可以将此语句视为将包含的文件复制到当前文件中。编译器然后编译整个文件,就好像您在一个大文件中编写了所有代码一样。

回答by Daniel Earwicker

I think the other answers are missing the point slightly. In all of C++, Java and C#, the using/importthing is entirely optional. So that's not different.

我认为其他答案略微忽略了这一点。在所有 C++、Java 和 C# 中,using/import事物完全是可选的。所以这没什么不同。

And then you have to do something else to make code be visible anyway, in all three platforms.

然后你必须做一些其他的事情来使代码在所有三个平台上都可见。

In C++, you minimally have to include it into the current translation unit (good enough for many implementations of vector, string, etc.), often you have to add something to your linker as well, although some libraries do that automatically based on the include (e.g. boost when building on Windows).

在 C++ 中,您至少必须将它包含到当前的翻译单元中(对于向量、字符串等的许多实现来说已经足够了),通常您还必须向链接器添加一些内容,尽管有些库会根据包括(例如在 Windows 上构建时增强)。

And in C# you have to add a reference to the other assembly. That takes care of the equivalent of includes and link settings.

而在 C# 中,您必须添加对其他程序集的引用。这相当于包含和链接设置。

And in Java you have to ensure the code is on the classpath, e.g. adding the relevant jar to it.

在 Java 中,您必须确保代码在类路径上,例如向其中添加相关的 jar。

So there are very closely analogous things required on all three platforms, and the separation between using/import(a convenience) and actual linkage resolution (a requirement) is the same in all three.

因此,所有三个平台都需要非常相似的东西,并且using/ import(方便)和实际链接解析(要求)之间的分离在所有三个平台中都是相同的。

回答by JohnIdol

You need to understand namespacesif you want to truly understand this.

如果你想真正理解这一点,你需要理解命名空间

With includeyou are just including the header file.

随着include你只是包括头文件。

With using namespaceyou are declaring you are using a given namespace that contains stuff such as cout. so if you do this:

随着using namespace您声明您正在使用包含诸如 cout 之类的内容的给定命名空间。所以如果你这样做:

using namespace std;

to you use coutyou can just do

cout你可以使用你可以做的

cout << "Namespaces are good Fun";

instead of:

代替:

std::cout << "Namespaces are Awesome";

Note that if you do not #include <iostream>you won't be able to use neither std::coutnor coutin your declarations and so forth because you're not including the header.

请注意,如果您不这样做,#include <iostream>您将无法在您的声明等中使用std::cout或使用cout,因为您没有包含标题。

回答by PolyThinker

One liner (not that this is something new :)):

一个班轮(不是说这是新东西:)):

using stdallows you to omit std::prefix, but you cannot use coutat all without iostream.

使用 std允许您省略std::前缀,但如果没有iostream则根本无法使用cout

回答by user2859314

In C++, the include directive will copy and paste the header file into your source code in the preprocessing step. It should be noted that a header file generally contains functions and classes declared within a namespace. For example, the <vector>header might look similar to something like this:

在 C++ 中,include 指令将在预处理步骤中将头文件复制并粘贴到您的源代码中。应该注意的是,头文件通常包含在命名空间内声明的函数和类。例如,<vector>标题可能类似于以下内容:

namespace std {
    template <class T, class Allocator = allocator<T> > class vector;
    ...
} 

Supposing you need to define a vector in your main function, you do #include <vector>and you have the piece of code above in your code now:

假设你需要在你的主函数中定义一个向量,你可以这样做#include <vector>并且你现在在你的代码中拥有上面的一段代码:

namespace std {
    template <class T, class Allocator = allocator<T> > class vector;
    ...
}
int main(){
   /*you want to use vector here*/
}

Notice that in your code the vector class is still located in the stdnamespace. However, your main function is in the default globalnamespace, so simply including the header will not make the vector class visible in globalnamespace. You have to either use usingor do prefixing like std::vector.

请注意,在您的代码中,vector 类仍然位于std命名空间中。但是,您的 main 函数位于默认global命名空间中,因此仅包含标头不会使向量类在global命名空间中可见。你必须使用using或做前缀像std::vector.