• C++命名空间(namespace)


    c++中,名称(name)可以是符号常量、变量、函数、结构、枚举、类和对象等等。工程越大,名称互相冲突性的可能性越大。另外使用多个厂商的类库时,也可能导致名称冲突。为了避免,在大规模程序的设计中,以及在程序员使用各种各样的C++库时,这些标识符的命名发生冲突,标准C++引入关键字namespace(命名空间/名字空间/名称空间),可以更好地控制标识符的作用域。

    创建一个命名空间:

    namespace A{
        int a = 10;
    }
    namespace B{
        int a = 20;
    }
    void test(){
        cout << "A::a : " << A::a << endl;
        cout << "B::a : " << B::a << endl;
    }

    命名空间只能全局范围内定义(以下错误写法

    void test(){
        namespace A{
            int a = 10;
        }
        namespace B{
            int a = 20;
        }
        cout << "A::a : " << A::a << endl;
        cout << "B::a : " << B::a << endl;
    }

    命名空间可嵌套命名空间

    namespace A{
        int a = 10;
        namespace B{
            int a = 20;
        }
    }
    void test(){
        cout << "A::a : " << A::a << endl;
        cout << "A::B::a : " << A::B::a << endl;
    }

    命名空间是开放的,即可以随时把新的成员加入已有的命名空间中

    namespace A{
        int a = 10;
    }
    
    namespace A{
        void func(){
            cout << "hello namespace!" << endl;
        }
    }
    
    void test(){
        cout << "A::a : " << A::a << endl;
        A::func();
    }

    声明和实现可分离

    #pragma once
    
    namespace MySpace{
        void func1();
        void func2(int param);
    }
    void MySpace::func1(){
        cout << "MySpace::func1" << endl;
    }
    void MySpace::func2(int param){
        cout << "MySpace::func2 : " << param << endl;
    }

    无名命名空间,意味着命名空间中的标识符只能在本文件内访问,相当于给这个标识符加上了static,使得其可以作为内部连接

    namespace{
        
        int a = 10;
        void func(){ cout << "hello namespace" << endl; }
    }
    void test(){
        cout << "a : " << a << endl;
        func();
    }

    命名空间别名

    namespace veryLongName{
        
        int a = 10;
        void func(){ cout << "hello namespace" << endl; }
    }
    
    void test(){
        namespace shortName = veryLongName;
        cout << "veryLongName::a : " << shortName::a << endl;
        veryLongName::func();
        shortName::func();
    }

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

    using声明

    using声明可使得指定的标识符可用。

    namespace A{
        int paramA = 20;
        int paramB = 30;
        void funcA(){ cout << "hello funcA" << endl; }
        void funcB(){ cout << "hello funcA" << endl; }
    }
    
    void test(){
        //1. 通过命名空间域运算符
        cout << A::paramA << endl;
        A::funcA();
        //2. using声明
        using A::paramA;
        using A::funcA;
        cout << paramA << endl;
        //cout << paramB << endl; //不可直接访问
        funcA();
        //3. 同名冲突
        //int paramA = 20; //相同作用域注意同名冲突
    }

    using声明碰到函数重载     

    如果命名空间包含一组用相同名字重载的函数,using声明就声明了这个重载函数的所有集合。

     1 namespace A{
     2     void func(){}
     3     void func(int x){}
     4     int  func(int x,int y){return x+y;}
     5 }
     6 void test(){
     7     using A::func;
     8     func();
     9     func(10);
    10     func(10, 20);
    11 }

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

    using编译指令

    using编译指令使整个命名空间标识符可用.

     注意:使用using声明或using编译指令会增加命名冲突的可能性。也就是说,如果有名称空间,并在代码中使用作用域解析运算符,则不会出现二义性。

    namespace A{
        int paramA = 20;
        int paramB = 30;
        void funcA(){ cout << "hello funcA" << endl; }
        void funcB(){ cout << "hello funcB" << endl; }
    }
    
    void test01(){
        using namespace A;
        cout << paramA << endl;
        cout << paramB << endl;
        funcA();
        funcB();
    
        //不会产生二义性
        int paramA = 30;
        cout << paramA << endl;
    }
    
    namespace B{
        int paramA = 20;
        int paramB = 30;
        void funcA(){ cout << "hello funcA" << endl; }
        void funcB(){ cout << "hello funcB" << endl; }
    }
    
    void test02(){
        using namespace A;
        using namespace B;
        //二义性产生,不知道调用A还是B的paramA
        //cout << paramA << endl;
    }

     

    命名空间使用

    需要记住的关键问题是当引入一个全局的using编译指令时,就为该文件打开了该命名空间,它不会影响任何其他的文件,所以可以在每一个实现文件中调整对命名空间的控制。
    比如,如果发现某一个实现文件中有太多的using指令而产生的命名冲突,就要对该文件做个简单的改变,通过明确的限定或者using声明来消除名字冲突,这样不需要修改其他的实现文件。

     

  • 相关阅读:
    Oracle递归查询,Oracle START WITH……CONNECT BY查询
    jquery Ajax请求示例,jquery Ajax基本请求方法示例
    Jquery EasyUI Combotree和 EasyUI tree展开所有父节点和获取完整路径
    Jquery EasyUI Combotree根据选中的值展开所有父节点
    Jquery EasyUI Combotree 初始化赋值
    Jquery EasyUI Combotree只能选择叶子节点且叶子节点有多选框
    SpringBoot Mybatis整合(注解版),SpringBoot集成Mybatis(注解版)
    SpringBoot Druid整合,SpringBoot 集成Druid
    安卓TTS语音合成经验分享(科大讯飞语音+)集成
    delphi7的新生,参与分布式应用开发,调用RESTful API,Json的应用
  • 原文地址:https://www.cnblogs.com/mmc9527/p/10429360.html
Copyright © 2020-2023  润新知