namespace 极简总结
命名空间作用 :划分独立作用域,解决同名变量 / 函数冲突,模块化管理代码;用
::访问空间内成员。两种 using 用法
using 命名空间::名字(using 声明):仅引入单个符号,冲突少,工程推荐;
using namespace 命名空间(using 指令):引入全部符号,简写方便但易重名,仅小型程序用。嵌套命名空间 :空间内再套空间,层级管理;C++17 可简写
A::B,多层::访问。匿名命名空间:无名称,内部内容仅当前文件可见,替代 static 做文件私有函数 / 变量。
命名空间别名 :
namespace 别名 = 原空间,简化超长嵌套命名空间书写。
- 定义命名空间
语法:
cpp
运行
namespace 空间名 { // 变量、函数、类、结构体 int a = 10; void func() {} }二、访问命名空间元素:using 声明 /using 指令
- 限定符直接访问(基础写法)
不使用任何 using,每次写全空间名:
cpp
运行
std::cout << LibA::a << endl; LibA::func();
- using 声明(using 标识符)
语法:
using 空间::名字;作用:只引入单个指定符号,仅该名字可直接使用,其他符号仍需加空间前缀。cpp
运行
#include <iostream> using std::cout; // 只引入std里的cout int main() { cout << "直接用cout" << endl; // cin 未声明,必须写 std::cin std::cin >> x; return 0; }
- using 指令(using namespace 空间)
语法:
using namespace 空间名;作用:一次性引入整个空间所有符号,空间内所有名称都可无前缀使用。cpp
运行
#include <iostream> using namespace std; // 导入std全部内容 int main() { cout << "hello"; cin >> x; endl; return 0; }三、嵌套命名空间
- 概念
命名空间内部再定义 namespace,形成层级结构,适合多层级代码分组(如项目→模块→工具)。
- 定义方式
老式写法(C++17 前)
cpp
运行
namespace Project { namespace Net { void send() { cout << "网络发送" << endl; } } }C++17 简化语法(推荐)
cpp
运行
namespace Project::Net { void send() {} }
- 使用嵌套命名空间
多层
::逐层访问:cpp
运行
// 完整写法 Project::Net::send(); // 搭配using简化 using namespace Project::Net; send();四、匿名命名空间 + 命名空间别名
- 匿名命名空间(无名字 namespace)
定义
cpp
运行
namespace { int temp = 100; void helper() {} }核心特性 & 作用
作用域仅限当前文件 :等价于加
static,其他 cpp 文件无法访问里面的内容;替代全局 static 变量 / 函数,C++ 推荐优先用匿名空间;
使用场景:只在当前源文件内部使用的工具函数、临时变量,防止跨文件命名冲突。
使用
匿名空间内的符号直接使用,无需前缀:
cpp
运行
helper(); cout << temp;
- 命名空间别名(给长空间简写)
语法:
namespace 别名 = 原空间名;解决多层嵌套、超长命名空间书写繁琐问题。cpp
运行
// 超长嵌套空间 namespace Game::Logic::Battle::Skill { void fire() {} } // 设置别名 namespace Skill = Game::Logic::Battle::Skill; // 使用别名调用 Skill::fire();也可给普通空间起别名:
cpp
运行
namespace A = LibA; A::print();
二、nullptr(C++11 空指针)
nullptr关键字,类型std::nullptr_t,专门代表空指针对比 NULL / 0
NULL 是宏
#define NULL 0,本质整型;0 是字面量 int重载场景下 NULL/0 会匹配 int 版本,产生歧义;nullptr 只会匹配指针
- 转换规则
nullptr 可隐式转为任意指针类型
普通指针不能隐式转 nullptr_t
- 规范:C++11 后统一用 nullptr,不用 NULL、0 表示空指针
class & struct 完整知识点梳理
一、基础核心区别
本质相同
class、struct都属于自定义复合类型,都能写:成员变量、成员函数、构造、析构、重载、继承、多态等,语法几乎互通。两大默认差异(考点核心)
1)默认成员访问权限
struct:所有成员默认 public
class:所有成员默认 private 示例:cpp
运行
struct S { int a; // public }; class C { int a; // private };2)默认继承方式
cpp
运行
// struct 默认 public 继承 struct Son : Base {}; // class 默认 private 继承 class Son : Base {};二、三种访问权限 public /protected/private
public 公有 外部任意代码、子类、自身都能直接访问。
protected 保护 仅自身 + 派生类可以访问,外部不能访问。
private 私有 只有类内部自身能访问,子类、外部均不可访问。
手动修改权限:用访问控制块分段声明
cpp
运行
class Test { private: int x; protected: int y; public: void func(){} };
四、函数重载(静态多态)
定义:同一作用域,同名函数,参数列表不同(个数 / 类型 / 顺序)
不能作为重载区分:仅返回值不同、仅参数名不同
重载解析:编译器自动匹配实参,优先级:精确匹配 > 提升转换 > 普通转换;多重等价匹配会报歧义
重载 vs 函数模板
重载:手动写每个版本,逻辑可不同,类型固定有限
模板:一套代码自动生成多类型,逻辑统一,扩展性强
五、inline 内联函数
inline 只是给编译器的优化建议,非强制命令
作用:调用处展开函数体,消除函数调用压栈跳转开销
使用规范
短小函数(1~5 行、无循环 / 递归)放头文件,加 inline,解决多文件 include 重复定义报错
复杂函数(循环、递归、代码量大)放 cpp,不用 inline,编译器会直接忽略 inline
验证方式:编译加 - O2 优化,查看汇编,无 call 指令代表成功内联
类内直接定义的成员函数,默认隐式 inline
六、const 全场景
- const 普通变量
初始化后不可修改,定义时必须赋值;有类型、作用域,优于 #define 宏
const 指针(必考区分)
const int* p指向常量指针:内容不可改,指针可换指向
int* const p指针常量:指针地址固定,内容可修改
const int* const p双重 const:内容、指针均不可改const 修饰函数参数
const T&只读引用,函数内禁止修改外部数据,避免拷贝,提升安全
- const 修饰返回值
返回
const T* / const T&,外部无法通过返回值修改内部数据;内置类型加 const 无意义
- const 成员函数
函数末尾加 const,承诺不修改类成员;mutable 修饰变量例外,const 函数内仍可修改 规则:const 对象只能调用 const 成员函数