我正在阅读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行?
答案 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,那么他们的代码将不再编译,并且他们很难知道原因。
顺便说一句,这也是为什么宏现在被认为是邪恶的原因。