欢迎光临
我们一直在努力

C++ using

全局变量与命名空间

  • 命名空间内的变量本质仍是全局变量 定义在 namespace 里面的变量,存储在全局数据区,生命周期贯穿整个程序,同命名空间函数可以直接读写,不需要传参
    误区:以为函数必须传参才能修改变量,LV 在命名空间内,属于全局作用域,函数直接访问
    类比:删掉 namespace,就是 C 语言普通全局变量
  • namespace Arr{
    int LV; // 全局变量,存全局数据段
    int add(int lv){
    LV += lv; // 直接访问同命名空间全局LV
    return LV;
    }
    }

  • 调试验证思路
    ● 在变量定义、函数调用行打断点
    ● 打开反汇编 / 内存窗口,查看Arr::LV内存地址
    ● 进入函数内部,观察操作的内存地址和外部完全相同,证明是同一个变量
  • using 的 3 种用法

    ① using 指令:引入整个命名空间
    语法:using namespace std;
    原理:编译器在当前作用域找不到名字时,自动去 std 里面查找

    using namespace std;
    cout << "hello"; //不用std::前缀

    ⚠️缺点:命名空间污染,如果自己定义了同名标识符,会冲突
    就近原则:局部 / 当前作用域名字优先,再去 using 引入的命名空间查找
    ② using 声明:只引入单个成员(推荐)
    语法:using std::cout; 只把cout引入当前作用域,其他 std 成员仍然要写std::,污染最小

    #include<iostream>
    using std::cout;
    using std::endl;
    int main(){
    cout << "test" << endl;
    return 0;
    }

    ③ using 定义类型别名(替代 typedef)
    语法:using 新名字 = 原类型; 编译期处理,运行无开销,适合复杂类型

    using Integer = int;
    using PtrInt = int*;
    Integer a = 100;

    和 typedef 对比:typedef int Integer; using 可读性更强,处理模板类型别名优势巨大

    命名空间嵌套

    namespace Outer{
    namespace Inner{
    void foo(){ }
    }
    }
    //全限定访问
    Outer::Inner::foo();
    //using声明单独引入
    using Outer::Inner::foo;
    foo();

    最佳编码实践

  • ❌头文件严禁写using namespace xxx;,会污染所有 include 该头文件的文件,极易重名冲突
  • ✅源文件 (.cpp) 可以酌情使用;优先用单个 using 声明(using std::cout),而不是全局 using namespace
  • using 全部是编译期处理,不会产生任何代码,不影响运行性能
  • 汇总

  • namespace 里面的变量是全局变量,不是类成员;类成员需要对象调用,namespace 变量不需要实例化对象
  • using 不是运行时代码,只是告诉编译器去哪里找名字,不增加程序体积
  • using 指令(using namespace std)和 using 声明(using std::cout)是两个东西,语法、作用范围不同
  • 就近原则:局部变量 > 当前命名空间 > using 引入的命名空间
  • 对比:namespace 和 class

    namespaceclass
    实例化 直接 :: 访问 通过 . 访问成员
    成员 全局生命周期变量 对象生命周期
    访问控制 无 private/public 有访问权限控制
    赞(0)
    未经允许不得转载:171主机测评 » C++ using
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址