• [C++再学习系列] Using声明和指令的工作原理


      对于C++编译器,那些名字可见至关重要,太多的名字可见将导致名字查找效率的降低,而名字太少将导致无法找到所需类型或函数的名字,从而导致编译错误。除了最常用的include可以导入可见名字之外,using关键字也可以导入名字到特定的编译单元中(单个cpp文件)。

    区别:

    Using声明: usingnamespace std; -- 导入某个名字空间可见的名字实体

    Using指令: using N::Widget; -- 导入特定名字

      Using用于导入特定名字空间下的名字实体,可以是全部名字实体(usingnamespace std;),也可以是特定的名字实体(using std::map;)。

      工作原理:using声明将获取的是在遇到using声明瞬间所见到的名字空间中的实体。这点是可以理解的,这样的工作方式有利于避免名字冲突(过多导致污染),加快名字查找过程。但这同时意味着:只有在using namespace std;语句之前所include的std头文件的名字实体被引入,即using并未引入所有来自std的名字实体。

      Using关键字定理:绝对不要在include之前使用using声明或指令。

      推论:不要在头文件中使用using声明或指令,相反应该使用名字空间限定所有的名字,尤其是来自其他名字空间的名字。(原因:1)头文件并不知道完全的include信息,头文件总是被用于其他cpp中,其后总会出现另外的include; 2)避免不必要的名字污染)

      例子:

    // 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 iscalled?

    }

      这几个文件先后出现顺序将决定f(1)是否可编译(所有的f函数定义均不可见)?以及重载哪个函数(哪些函数可见,并参与重载)。

      错误地使用using将导致名字空间污染,或错误地导入不完整的名字空间的瞬间快照(导致无法找到特定名字实体)。在头文件中,使用using将使这个问题更加严重(多处使用,使用顺序不可控)。

      例外:编写类成员级的using声明导入所需的基类成员名字是一个合法技巧,只有这样才能避免基类的名字被屏蔽,如重载函数不可见问题。(见派生类的函数重载)

    相关文章:揭秘:C++编译器的函数编译流程

    ----------------------------------------------------

    兄弟的公司:立即购--手机购物,诚信网购

    欢迎转载,请注明作者和出处。

  • 相关阅读:
    webpack2.x抽取css
    window.print控制打印样式
    Vue2.x中的父子组件相互通信
    Vue2.x中的父组件数据传递至子组件
    NodeJs之fs的读写删移监
    设计
    mycat服务启动{管理模块启动过程}
    mycat初探
    zookeeper总结
    rocketmq总结
  • 原文地址:https://www.cnblogs.com/zhenjing/p/1868891.html
Copyright © 2020-2023  润新知