http://stackoverflow.com/questions/5849457/using-namespace-in-c-headers

http://stackoverflow.com/questions/5849457/using-namespace-in-c-headers 

這篇有解釋 避免在 header用 using namespace, 以免header被其他人include後 造成Conflict

n all our c++ courses, all the teachers always put using namespace std; right after the #includes in their .h files. This seems to me to be dangerous since then by including that header in another program I will get the namespace imported into my program, maybe without realizing, intending or wanting it (header inclusion can be very deeply nested).

So my question is double: Am I right that using namespace should not be used in header files, and/or is there some way to undo it, something like:

//header.h
using namespace std {
.
.
.
}

One more question along the same lines: Should a header file #include all the headers that it's corresponding .cpp file needs, only those that are needed for the header definitions and let the .cpp file #include the rest, or none and declare everything it needs as extern?
The reasoning behind the question is the same as above: I don't want surprises when including .h files.

Also, if I am right, is this a common mistake? I mean in real-world programming and in "real" projects out there.

Thank you.

You should definitely NOT use using namespace in headers
for precisely the reason you say, that it can unexpectedly change the
meaning of code in any other files that include that header. There's no
way to undo a using namespace which is another reason it's so dangerous. I typically just use grep or the like to make sure that using namespace isn't being called out in headers rather than trying anything more complicated. Probably static code checkers flag this too.

The header should include just the headers that it needs to compile.
An easy way to enforce this is to always include each source file's own
header as the first thing, before any other headers. Then the source
file will fail to compile if the header isn't self-contained. In some
cases, for example referring to implementation-detail classes within a
library, you can use forward declarations instead of #include because you have full control over the definition of such forward declared class.

I'm not sure I would call it common, but it definitely shows up once
in a while, usually written by new programmers that aren't aware of the
negative consequences. Typically just a little education about the
risks takes care of any issues since it's relatively simple to fix.

原文:I don’t want to see another “using namespace xxx;” in a header file ever again

  在这里,我毫不回避地说了这句话。

  作为一个开发者/团队领导者,我经常会去招聘新的项目成员,有时候也帮助其他组的人来面试应聘者。作为应聘流程之一,我经常要求应聘者 写一些代码,因此我检查过相当多的代码。在最近提交的 C++ 代码中,我注意到一个趋势,在任何头文件中,我总是能看到以下代 码:

using namespace std;

  如果我用我们的代码检查系统(在实践中我十分推荐这个系统)来检验代码,以上那行代码经常会跟着一句评论“Timo 不会这样写的”。他们说得很对,我确实不会这么写。

  那么,为什么我说服了很多 C++ 教材(也许并不是什么好事),让他们认为使用上面那段代码是非常坏的方式?让我们先来看看上面那段代码做了什么。总的来说,它把命名空间“std”以内的 所有内容(或者其他由作者用 using 调用命名空间)无一例外的引入了目前的命名空间中。请注意我说的“所有内容”,并不是一两个你想用的类\类型\模板。在一段代码的开头引入命 名空间的原因 则是加强程序模块化,和减少命名冲突。大体上,它允许你可以写类似下面的那段代码,并且保证编译器可以选择正确的实现:

std::vector<std::string> names;
my_cool_reimplementation::vector<our_internal_stuff::string> othernames;

  现在,假定我们正在尝试减少代码输入,并且在以上代码中使用 using 声明(或者更糟糕的,两个命名空间都声明了),按照如下代码来实现:

vector<string> names;
vector<our_internal_stuff::string> othernames;

  如果这段代码的作者很幸运的话,编译器会选择 vector 的正确实现,或者至少在最初的阶段会这么做。但是过了一段时间,你会碰到一些很奇怪的编译器错误。幸运的话,你能找到这些错误的原因——我曾经遇到过类似 问题,我花费了好几天才能找到这类问题的原因。该死,它们会浪费你很多的时间,仅仅因为你为了想少打 5 个字符的代码。

  并且,如果你把 using 声明用在了头文件中,你会让这 类问题更加恶化,因为命名冲突问题早晚都会在一个调用关系非常非常远的模块中神不知鬼不觉的出现,而你可能需要查三层调用才可以找到原因所 在,一个头文件包含了另一个直 接使用 using 声明的头文件可以导致命名空间被立刻污 染掉,任何一个使用命名空间的文件如果使用了 std 命名空间的内容,都会导致这类问题。

  那么,为什么你能在很多教科书中看到它们使用 using namespace std?我的理论是,它确实会帮助改善整本书的排版,并且能减少一些视觉的混乱。在一本纸质书中,你只有很有限的空间来写文字,因此你必须最大限度的利用 它,加之书中的代码例子通常都很简单。但另一方面,不同的命名空间限定符会带来了很多视觉混乱,这会让读者很难从上下文判断作者的意图。当你 想在这个时代 写一些有效率的代码的时候,以上两点都不完全对,现在的编译器大多数能每行处理 60-80 个单词(你可以试试,这可以的)。因此,不要乱引入命名空间。

  如果你非常明确的想在一个头文件中 使用 using 声明,应该怎么做?我们有其他途径可以减少不得不用 using 声明的情况——你可以用以下其中一种,或则多种方式的组合。

  首先,你只需使用 typedef。我会建议你使用这种方法,即使我并不经常遵循我自己的建议,我也认为无论如何这都是一个在实际应用中很好的方法。实际上,使用 typedef 有两个好处——他让一个类型名可读性增加,如果你选择了一个很好的名字,它可以让作者的意图更加显而易见。比较一下如下的声明方式:

std::map<std::string, long> clientLocations;
typedef std::map<std::string, long> ClientNameToZip;
ClientNameToZip clientLocations;

  第二个声明——即使它被展开为两行——也比第一个声明更加直观,同时,它也避免了命名空间模糊化。

  另外一个选择则是用两种方法来限制 using 声明的作用域——仅仅是你想用的那个“using” 符号,例如:

using std::string;

  但是,把这段声明扔到头文件中, 几乎和使用“using namespace”一样糟糕, 因此,你应该使用作用域来限制下它的可见性,来确保你的 using 声明真的只在第一次做 using 声明的地方有效。例如,你可以用如下方法限制类声明作用域:

namespace bar
{
struct zzz
{

};
}
class foo
{
using namespace bar;
zzz m_snooze; // Pulls in bar::zzz };

  或者,你可以直接把 using 的作用域限制到一个函数中,例如:

void temp ()
{
using namespace std;
string test = "fooBar";
}

  不管哪种方法,你都可以把 using 的作用域限制到需要使用它的代码中,而不是把它放到代码的公共空间中。你的工程越大,确保模块化,和最小化不可预料的负面影响就显得越发重 要。

原文:I don’t want to see another “using namespace xxx;” in a header file ever again的更多相关文章

  1. (转) [C++]我再也不想在任何头文件中看到using namespace xxx这种句子了(译)

    原文的传送:I don’t want to see another “using namespace xxx;” in a header file ever again 转自  http://blog ...

  2. ZIP压缩算法详细分析及解压实例解释

    最近自己实现了一个ZIP压缩数据的解压程序,觉得有必要把ZIP压缩格式进行一下详细总结,数据压缩是一门通信原理和计算机科学都会涉及到的学科,在通信原理中,一般称为信源编码,在计算机科学里,一般称为数据 ...

  3. 年度巨献-WPF项目开发过程中WPF小知识点汇总(原创+摘抄)

    WPF中Style的使用 Styel在英文中解释为”样式“,在Web开发中,css为层叠样式表,自从.net3.0推出WPF以来,WPF也有样式一说,通过设置样式,使其WPF控件外观更加美化同时减少了 ...

  4. Linux随笔之——./configure、make、make install(转)

    原文连接:http://www.linuxidc.com/Linux/2011-02/32211.htm 这些都是典型的使用GNU的AUTOCONF和AUTOMAKE产生的程序的安装步骤. ./con ...

  5. Flume NG Getting Started(Flume NG 新手入门指南)

    Flume NG Getting Started(Flume NG 新手入门指南)翻译 新手入门 Flume NG是什么? 有什么改变? 获得Flume NG 从源码构建 配置 flume-ng全局选 ...

  6. Serial Port Programming using Win32 API(转载)

    In this tutorial we will learn How to communicate with an external device like a microcontroller boa ...

  7. iOS之数据安全

    一.数据安全 术语----- 密钥:密钥是一种参数, 它是在明文转换为密文, 或将密文转换为明文的算法中输入的参数. 密钥分为对称密钥和非对称密钥(也可以根据用途来分为加密密钥和解密密钥) 明文:没有 ...

  8. Identify Memory Leaks in Visual CPP Applications —— VLD内存泄漏检测工具

    原文地址:http://www.codeproject.com/Articles/1045847/Identify-Memory-Leaks-in-Visual-CPP-Applications 基于 ...

  9. GPU深度发掘(一)::GPGPU数学基础教程

    作者:Dominik Göddeke                 译者:华文广 Contents 介绍 准备条件 硬件设备要求 软件设备要求 两者选择 初始化OpenGL GLUT OpenGL ...

随机推荐

  1. [转] electron实战开发详细流程

    [From] http://www.myk3.com/arc-8856.html 很久没有更新博客,人越来越懒了,唉 说好做的electron教程距离上次玩electron已经过去了好几个月了.. 这 ...

  2. mutillidae之注册页面的Insert型报错注入

    http://127.0.0.1/mutillidae/index.php?page=register.php 1.注册一个用户试一试,发现页面只提示用户注册成功信息,并五其它可回显信息,果断尝试盲注 ...

  3. CAPL编程实现诊断刷写,车联网FOTA流程自动化测试(代码篇)

    原创内容,转载请注明出处   接上篇,本文主要讲CAPL编程详细实现,软件环境CANoe  11.0 一.Simulation Setup 1.建模之前,首先创建一个.DBC文件.如果不会,可以用一个 ...

  4. vue组件(持续更新)

    1.vee-validate :vue的表单验证组件 网友博客介绍:https://www.cnblogs.com/xxwang/p/6104715.html

  5. zookeeper简单命令

    bin/zkCli.sh -server ls / create /zk_test my_data get /zk_test set /zk_test admln delete /zk_test ad ...

  6. css样式查找遇到的问题汇总

    利用css简单排除元素的第一个子元素 例如:排除表格的第一行 /*除了表格的第一行其他都显示为红色*/ table tr+tr{ background-color:red;/*除了表格的第一行其他都显 ...

  7. Unity3D 发布成PC端常用设置

    本文,基于Unity 5.6pro版本来发布PC端.文中若有不妥之处,欢迎各位指出! 一.如何去掉Unity官方水印? 首先,你需要pro版本的Unity3D.如果,你是personal版本的话,就需 ...

  8. lua-遍历集合-ipairs和pairs的区别

    --ipairs和pairs的区别arr = {1,3,[5]=5,name="kaikai",age=12, 89}--arr[4]= 23--ipairs--ipairs仅仅遍 ...

  9. Coursera 机器学习 第8章(上) Unsupervised Learning 学习笔记

    8 Unsupervised Learning8.1 Clustering8.1.1 Unsupervised Learning: Introduction集群(聚类)的概念.什么是无监督学习:对于无 ...

  10. 代码重构----使用java有限状态机来消除太多的if else判断

    1. 状态机基本概念 http://zh.wikipedia.org/wiki/%E6%9C%89%E9%99%90%E7%8A%B6%E6%80%81%E6%9C%BA 状态存储关于过去的信息,就是 ...