C++ 使用命名空间标准;在头文件中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14575799/
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 18:28:19  来源:igfitidea点击:

using namespace std; in a header file

c++classnamespacesheader-files

提问by RebelPhoenix

So, I have the following in a specification file

所以,我在规范文件中有以下内容

#include <string>
#include <fstream>
using namespace std:

class MyStuff
{
    private:

    string name;
    fstream file;
    // other stuff

    public:
    void setName(string);
}

I also have in the implementation file

我在实现文件中也有

#include "MyStuff.h"
using namespace std;

void MyStuff::setName(string name);
{
     name = name
}

and in the program file I have...

在程序文件中我有...

#include <iostream>
#include <string>
using namespace std;

void main()
{
     string name;
     MyStuff Stuff;

     cout << "Enter Your Name: ";
     getline(cin, name);

     Stuff.setName(name);
}

And I'm gathering that applying "using namespace std;" in a header file is a no-no, and that to fully qualify is the "better" practice; such as std::cout << stuff << endl;

我正在收集应用“使用命名空间标准;” 在头文件中是一个禁忌,完全合格是“更好”的做法;如std::cout << stuff << endl;

It is my understanding that in order to use a string, it must have the std namespace. Is that true?

我的理解是,为了使用字符串,它必须具有 std 命名空间。真的吗?

If so, in the header file, is more "pure/clean" to do it as...

如果是这样,在头文件中,将其作为更“纯/干净”来执行...

#include <string>

class MyStuff
{
     std::string name;
}

And, as I understand it currently, using namespace std; across all three files, specification, implementation, and program, essentially layers the three namespaces on top of each other, so if I separately declare string name;within each of the files, the compiler will not know which goes to what. Is that true?

而且,据我目前的理解,使用命名空间 std; 在所有三个文件、规范、实现和程序中,基本上将三个命名空间分层放置在彼此之上,所以如果我string name;在每个文件中单独声明,编译器将不知道哪个去哪个。真的吗?

I generally understand that being clear is a "good" thing to do, I am however a little unclear on the specificity of how, and I'm most interested in the deeper "why" that underlies it all.

我一般都明白,清楚是一件“好事”,但我对如何做的具体性有点不清楚,我最感兴趣的是更深层的“为什么”,这是这一切的基础。

So my direct question is, in my example provided, what is the "clearest" way to describe the function both for the compiler and for industry "standard"? And, can you direct me to resources that more clearly delineate the reasoning and practical implementation of namespaces.

所以我的直接问题是,在我提供的示例中,为编译器和行业“标准”描述函数的“最清晰”方式是什么?并且,您能否将我引向更清楚地描述命名空间的推理和实际实现的资源。

采纳答案by DevSolar

Let's say I declare a class stringmyself. Because I'm a lazy bum, I do so in global namespace.

假设我string自己声明了一个类。因为我是一个懒惰的流浪汉,所以我在全局命名空间中这样做。

// Solar's stuff
class string
{
    public:
        string();
        // ...
};

Some time later on, I realize that re-using some of yourcode would benefit my project. Thanks to you making it Open Source, I can do so:

一段时间后,我意识到重用您的某些代码将使我的项目受益。感谢您将其开源,我可以这样做:

#include <solarstuff.hpp>
#include <phoenixstuff.hpp>

string foo;

But suddenly the compiler doesn't like me anymore. Because there is a ::string(my class) and another::string(the standard one, included by your header and brought into global namespace with using namespace std;), there's all kinds of pain to be had.

但是突然编译器不再喜欢我了。因为有一个::string(我的类)和另一个::string(标准的,包含在你的头文件中并用 带入全局命名空间using namespace std;),所以会有各种各样的痛苦。

Worse, this problem gets promoted through every file that includes myheader (which includes your header, which... you get the idea.)

更糟糕的是,这个问题通过包含我的标题的每个文件(包括您的标题,...您明白了。)

Yes I know, in this example I am also to blame for not protecting my own classes in my own namespace, but that's the one I came up with ad-hoc.

是的,我知道,在这个例子中,我也应该为没有保护我自己的命名空间中的类而受到责备,但那是我临时想到的。

Namespaces are there to avoid clashes of identifiers. Your header not only introduces MyStuffinto the global namespace, but also everyidentifier from stringand fstream. Chances are most of them are never actually needed by either of us, so why dragging them into global, polluting the environment?

命名空间是为了避免标识符冲突。您的标头不仅引入MyStuff了全局命名空间,还引入了来自和 的每个标识符。有可能我们中的任何一个人实际上都不需要它们中的大多数,那么为什么要把它们拖到全球范围内,污染环境呢?stringfstream

Addition:From the view of a maintenance coder / debugger, foo::MyStuffis ten times more convenient than MyStuff, namespace'd somewhere else (probably not even the same source file), because you get the namespace information right there at the point in the code where you need it.

添加:从维护编码器/调试器的角度来看,foo::MyStuff它比MyStuff, 命名空间位于其他地方(甚至可能不是同一个源文件)方便十倍,因为您可以在代码中的位置获得命名空间信息需要它。

回答by Karthik T

Multiple instances of using namespace std;will not cause any ambiguity. The problem is that that statement imports all the names/types/functions of stdinto your namespace, and now if you want to name a class stringfor instance, you will hit into trouble. This is more likely to happen with functions like remove, erase, etc.

的多个实例using namespace std;不会造成任何歧义。问题是该语句将所有名称/类型/函数std导入到你的命名空间中,现在如果你想命名一个类string,你会遇到麻烦。这更可能发生在删除、擦除等函数中。

The use of it in headers is one level worsebecause that propagates to all the .cpps that header, without the awareness of person including it. Using it in .cppatleast needs a conscious choice.

在标题中使用的是一个水平更差,因为传播到所有的.cpps表示头,没有人,包括它的意识。.cpp至少使用它需要有意识的选择。

A more complete explanationcan be got at Why is "using namespace std" considered bad practice?

一个更完整的解释可在拿到为什么“使用命名空间std”被认为是不好的做法?

An example of issuesthat might result from this can be found in How to use an iterator?where the OP defines a function distance, and keeps getting the wrong answer. Another exampleat Confusion about pointers and references in C++

可以在如何使用迭代器中找到可能由此导致的问题示例OP 定义了一个函数distance,并不断得到错误的答案。又如约用C指针和引用混乱++

回答by billz

Namespace usings are for your convenience, not for you to inflict on others: Never write a using declaration or a using directive before an #include directive.

命名空间 using 是为了您的方便,而不是为了您对他人造成影响:永远不要在 #include 指令之前编写 using 声明或 using 指令。

Corollary: In header files, don't write namespace-level using directives or using declarations; instead, explicitly namespace-qualify all names. (The second rule follows from the first, because headers can never know what other header #includes might appear after them.)

推论:在头文件中,不要写命名空间级别的 using 指令或 using 声明;相反,明确命名空间限定所有名称。(第二条规则遵循第一条规则,因为标头永远无法知道其他标头 #includes 可能出现在它们之后。)

I generally understand that being clear is a "good" thing to do, I am however a little unclear on the specificity of how, and I'm most interested in the deeper "why" that underlies it all.

我一般都明白,清楚是一件“好事”,但我对如何做的具体性有点不清楚,我最感兴趣的是更深层的“为什么”,这是这一切的基础。

Below code snippets reflects why use using namespacein header file is bad:

下面的代码片段反映了为什么using namespace在头文件中使用不好:

// snippet 1
namespace A {
 int f(double);
}

// snippet 2
namespace B {  
    using A::f;
    void g();
}

// snippet 3
namespace A {
    int f(int);
}

// snippet 4
void B::g() {
    f(1);   // which overload is called?
}

So in your example, simply this one is better:

所以在你的例子中,这个更好:

#include <string>

class MyStuff
{
    std::string name;
};

Recommend book: C++ Coding Standards: 101 Rules, Guidelines, and Best Practices

推荐书籍:C++ Coding Standards: 101 Rules, Guidelines, and Best Practices

and link: Google C++ coding guide

和链接:Google C++ 编码指南