19

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

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

class MyStuff
{
    private:

    string name;
    fstream file;
    // other stuff

    public:
    void setName(string);
}

我在实现文件中也有

#include "MyStuff.h"
using namespace std;

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

在我的程序文件中......

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

void main()
{
     string name;
     MyStuff Stuff;

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

     Stuff.setName(name);
}

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

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

如果是这样,在头文件中,更“纯粹/干净”的做法是......

#include <string>

class MyStuff
{
     std::string name;
}

而且,据我目前了解,使用命名空间std;在所有三个文件(规范、实现和程序)中,基本上将三个命名空间叠加在一起,所以如果我string name;在每个文件中分别声明,编译器将不知道哪个到哪个。真的吗?

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

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

4

3 回答 3

16

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

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

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

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

string foo;

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

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

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

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

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

于 2013-01-29T05:00:40.363 回答
12

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

标头中使用它会更糟,因为它会传播到.cpp该标头的所有 s,而没有包括它的人的意识。使用它.cpp至少需要一个有意识的选择。

完整的解释可以在为什么“使用命名空间标准”被认为是不好的做法?

如何使用迭代器?OP 定义了一个函数distance,并不断得到错误的答案。Confusion 中关于 C++ 中指针和引用的另一个示例

于 2013-01-29T04:48:49.767 回答
2

命名空间使用是为了您的方便,而不是让您强加于他人:切勿在 #include 指令之前编写 using 声明或 using 指令。

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

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

下面的代码片段反映了为什么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?
}

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

#include <string>

class MyStuff
{
    std::string name;
};

推荐书籍:C++ 编码标准:101 条规则、指南和最佳实践

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

于 2013-01-29T04:56:33.333 回答