一、命名空间 namespace

1. 概念

命名空间用于定义新作用域,空间内所有成员都隶属于该命名空间,解决 C 语言全局命名冲突问题。
语法:namespace 空间名 { 成员; }{}内为命名空间成员。

  • 支持嵌套定义;
  • 同一工程允许存在多个同名命名空间,编译器会自动合并为同一个命名空间。

2. 三种使用方式

  1. 空间名::成员名(全限定,推荐,无命名污染)
std::string("hello");
  1. using 命名空间::成员:单独引入某个成员,如using std::string;
  2. using namespace 命名空间;:一次性引入空间所有成员,简单但容易引发命名冲突。

二、C++ 标准输入输出

C++ 标准库 IO 对象都位于std命名空间:

  • std::cin:标准输入
  • std::cout:标准输出
  • std::cerr:标准错误输出

三、函数缺省参数(默认参数)

1. 概念

声明 / 定义函数时,给形参指定默认值;调用函数不传实参时,自动使用默认值。

2. 分类

  • 全缺省参数:所有形参都设置默认值
  • 半缺省参数:部分形参设置默认值

3. 强制规则(重点)

  1. 半缺省必须从右往左连续给默认值,不能间隔设置;
  2. 默认参数不能在声明和定义中同时给出,二选一(一般写在函数声明头文件);
  3. 默认值只能是常量 / 全局变量

四、函数重载 & extern "C"

1. 函数重载

同一作用域下,函数名相同、形参列表不同(个数 / 类型 / 顺序),构成函数重载;
仅返回值不同,无法构成重载。

原理:C++ 支持重载依靠名字修饰 (name mangling),编译器根据形参信息修改函数符号名;C 语言不支持名字修饰,所以 C 语言没有重载。

2. extern "C"

作用:指定代码按照C 语言编译规则处理,关闭 C++ 名字修饰。
用法两种形式:

// 1. 修饰单个函数
extern "C" void func();

// 2. 代码块批量修饰
extern "C" {
    void func1();
    void func2();
}

注意:被extern "C"修饰的函数不能重载

常见场景:C++ 代码调用 C 库、C 代码调用 C++ 编写的接口。

五、引用 reference

1. 概念

引用不是新变量,是已有变量的别名;编译器不为引用开辟独立内存,和原变量共享同一块空间。
语法:类型& 别名 = 原变量;

2. 核心特性

  1. 定义时必须初始化
  2. 一个变量可以拥有多个引用;
  3. 引用一旦绑定某个实体,无法再绑定其他实体
  4. const修饰变量,只能用const引用接收。

3. 典型使用场景

  • 做函数参数:减少拷贝,可实现输出型参数
  • 做函数返回值(注意:不能返回局部变量引用!局部变量销毁后引用失效)

六、引用 vs 指针

  1. 初始化:引用定义必须初始化;指针无强制要求;
  2. 重定向:引用绑定实体后不能更改指向;指针可以随时指向同类型其他变量;
  3. 空值:不存在 NULL 引用;存在 NULL 指针;
  4. sizeof结果:
    • sizeof(引用):得到原变量大小
    • sizeof(指针):固定是地址长度(32 位 4 字节 / 64 位 8 字节);
  5. 自增运算:ref++等价原变量+1ptr++代表指针向后偏移一个类型长度;
  6. 多级:支持多级指针;不存在多级引用
  7. 访问实体:指针需要手动*解引用;引用编译器自动处理;
  8. 安全性:引用相对指针更安全,减少野指针风险。

七、内联函数 inline

1. 概念

inline修饰的函数为内联函数。编译阶段,编译器直接把函数代码展开到调用位置,消除函数调用栈帧压栈 / 出栈开销,提升运行效率。

2. 特性

  1. inline只是给编译器的建议,编译器自主优化;函数体内存在递归、循环时,编译器大概率忽略 inline;
  2. 声明和定义不能分离!分离会导致链接错误;头文件写 inline 函数,实现直接放头文件;

原因:展开需要看到完整函数体,分离后链接阶段找不到函数代码。

3. 适用场景

适合:代码简短、频繁调用的小函数
不适合:代码长、带有递归 / 循环的函数(代码展开会造成代码膨胀)