• 命名空间理解


    转自:https://bbs.csdn.net/topics/300176441,https://blog.csdn.net/qq_41230365/article/details/80191964

    1.头文件不能使用using 

    在一段代码的开头引入命名空间的原因则是加强程序模块化,和减少命名冲突。 

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

    代替做法:

    • 使用typedef:
    std::map<std::string, long> clientLocations;  
    typedef std::map<std::string, long> ClientNameToZip;  
    ClientNameToZip clientLocations;  
    • 使用using符号,限制作用域
    using std::string;  

    但上述声明仍不能放到头文件中。应该使用作用域来限制下它的可见性,来确保你的using声明真的只在第一次做using声明的地方有效。例如:

    namespace bar  
    {  
      struct zzz  
      {  
        …  
      };  
    }  
    class foo  //bar命名空间的作用域在该类中
    {  
      using namespace bar;  
      zzz m_snooze; // Pulls in bar::zzz   
    };  
    
    
    void temp()  
    {  
      using namespace std;  //把作用域限制在一个函数中
      string test = "fooBar";  
    }  

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

    2.作用

    using namespace用来确定编译时缺省查找的名字空间。 

    如果编译器发现某个名字在多个缺省的名字空间都出现过,会显示编译错误,这时就必须使用::操作符强行指定名字空间了。 例如你自己定义了一个变量,名字也叫cout。这时你就必须指定是std::cout还是::cout(直接使用::表示根名字空间)。
    如果有相同的函数名,那么可以使用不同的命名空间:
    using namespace name1;
    using namespace name2;
    
    name1::test(); // 不同命名空间中的相同的函数名,通过前面的命名空间来区分。
    name2::test();

    3.嵌套命名空间 

     https://blog.csdn.net/Fourier_Legend/article/details/82225279
    #include <stdlib.h>
    
    #include <iostream>
    
    namespace detail // 定义一个namespace
    {
    const int i=99;
    }
    
    namespace ant // namespace 嵌套
    {
        namespace blas
        {
            const int i=0;
        }//end blas
    
        const int i=3;
    
        namespace detail
        {
        const int i=33;
        void test()
        {
            std::cout<<"i:"<<i<<std::endl;  // 33
            std::cout<<"::detail::i"<<::detail::i<<std::endl; // 99 从根命名空间开始的detail空间
            std::cout<<"detail::i"<<detail::i<<std::endl; // 33 当前的detail空间
            std::cout<<"::ant::blas::i:"<<::ant::blas::i<<std::endl;// 0 ::ant 表根命名空间
            std::cout<<"ant::blas::i"<<::ant::blas::i<<std::endl;   // 0
            std::cout<<"blas::i"<<blas::i<<std::endl;   // 0 平级
            //std::cout<<"::blas::i"<<::blas::i<<std::endl;   // error
            std::cout<<"ant::i"<<ant::i<<std::endl;// 3
        }
        }// end detail
    
    }//end namespace ant
    
    using namespace std;
    int main()
    {
        ant::detail::test(); // 引用test() 需要:: 限定符
        return 0;
    }

     从上面的代码来理解,根命名空间就是它不被别的命名空间嵌套,是第一级别的。嵌套命名空间using方法:

    namespace ABC
    {
            void fun1(){printf("this is fun1.\n");}
    
            namespace map
            {
                    void fun2(){printf("this is fun2.\n");}
            }
    }
    
    using namespace ABC;
    using namespace ABC::map;  //使用两个namespace, 相当于把两个空间中的变量和函数都抠出来,供本函数使用
    
    int _tmain(int argc, _TCHAR* argv[])
    {
            fun1();
            fun2();
    
            return 0;
    }
  • 相关阅读:
    前端模块化
    PHP如何实现第三方分享
    python3运算符
    Python3基本数据类型
    Python3基本语法
    php 文件缓存
    php 链接转二维码图片
    php 根据文件内容来判断文件类型
    mysql中查询常用的关键字
    php天龙八部
  • 原文地址:https://www.cnblogs.com/BlueBlueSea/p/16837877.html
Copyright © 2020-2023  润新知