在C ++中的头实现中使用“using”关键字

时间:2013-11-12 21:17:54

标签: c++ header-files

我正在阅读Accelerated c++第4章,他们教导如何在不同的文件中划分c ++程序。在这里,他们写道我们不应该在头文件中使用“using _ :: ”构造,因为包含头的人可能想要使用不同的实现。但是在头文件中实现方法时,使用“使用”很好。你能澄清一下吗?在链接实现对象文件时,程序最终是否会使用“using ::”构造?这是代码:

//median.h file
#ifndef GUARD_median_h
#define GUARD_median_h
#include <algorithm>
#include <vector>

double median(std::vector<double>); // <<<<<<<< no "using std::vector"
#endif

但是在median.cpp:

#include <vector>
#include <stdexcept>

using std::vector; // <<<<< "using" construct used
using std::domain_error; // <<<<< "using" construct used

double median(vector<double> vec){
    if(vec.size() == 0) throw domain_error("median for an empty vector not defined");
    //....... rest of the implementation
}

澄清一点:

这是我的客户端调用上面的标题:

#include "median.h"
using my_vector_impl::vector;
//..some function...
    std::vector v1;
    double med = median(v1);

我是否正确地说我们在标题中阻止“使用std :: vector”以便我们可以在上面的代码中使用第2行?

3 个答案:

答案 0 :(得分:6)

using只是缩短名称的编译时快捷方式。它在运行时没有任何影响。此外,它只影响处于或低于其自身范围的源代码,因此如果您在实现文件中使用它,没有其他文件可以看到它,但如果您在标头中使用它,则包含标题的所有文件将包含using,其名称空间将被污染。

编辑:

要回答您更新的问题,您的示例并不完全是为什么您应该避免标题中的using。这就是原因:

// Header:

using std::vector;

// Client:

#include <Header>

class vector { ... };

void f() {
    vector v; // Ambiguous because of something out of my control
}

这是您要避免的情况。您不希望告诉使用您的库的人可以使用哪些名称,当您执行using时,您正在执行此操作。

答案 1 :(得分:3)

这只是意味着您可以将using …放入C ++源代码中。您还可以合理地将其放在您包含的私有标头中,但不包括外部用户。您只是不想弄乱客户端的环境,并将using放在他们需要包含的标题中就可以了。

在链接实现对象文件时,程序最终是否会使用“using ::”构造? using关键字只是对编译器的一种便利,而不是改变所链接的内容。它只影响使用它的来源。

答案 2 :(得分:2)

“using”声明只是一个编译时构造,使您不必反复键入std ::(或其他命名空间)。在您自己的.cpp实现文件中,可以使用using声明,因为您可以控制该文件。如果将其包含在.h(标题)文件中,则包含该标题的每个文件也将包括您的使用声明,包括您无法控制的声明,甚至可能从未听说过。

一个典型的例子是使用tr1 :: shared_ptr和vsd :: shared_ptr的实现文件,后者才会出现。如果您的头文件包含std :: shared_ptr,那么他们的代码将不再编译,并且他们很难知道原因。

顺便说一句,这也是为什么宏现在被认为是邪恶的原因。