基础语法与数据类型
基本类型与复合结构
C++ 的基础类型包括整型(int、short、long)、浮点型(float、double)、字符型(char)和布尔型(bool)。在构建复杂数据结构时,我们会用到数组、结构体、联合体以及枚举。指针和引用是 C++ 的灵魂:指针存储地址,而引用则是变量的别名。
常量与变量的深度解析
const 修饰的变量必须初始化。当它修饰指针时,有三种常见情况:
const T* p:指向常量的指针,内容不可改。T* const p:常量指针,指针本身不可改。const T* const p:两者都不可改。 此外,const修饰成员函数(如void func() const;)表示该函数不会修改类的成员变量(除非使用mutable)。
对比 #define 宏,const 具有类型检查优势,且 constexpr 强制编译期计算,可用于函数或构造函数,要求表达式无副作用。例如 constexpr int sum(int a, int b) { return a + b; },调用时会在编译期算出结果。
指针与引用的进阶技巧
空指针推荐使用 C++11 的 nullptr,它比 NULL(本质是 0 的宏)更安全。野指针和悬空指针是常见的未定义行为来源,务必注意内存生命周期。
引用的本质是编译器优化的指针,底层占用指针大小的内存,但语法上无地址操作。常引用(const T&)可绑定临时对象,延长其生命周期。作为函数返回值时,切勿返回局部变量的引用,这会导致悬空问题;常用于实现链式调用,如 ostream& operator<<(ostream& os, const T& val)。
核心区别在于:引用不能为空且初始化后不可改指向,指针则灵活得多;sizeof(引用) 是所指对象的大小,而 sizeof(指针) 固定。
函数机制与右值引用
函数重载依据参数列表(个数、类型、顺序),与返回值无关。默认参数必须从右往左连续指定,且在声明和定义中只能出现一次。
C++11 引入的右值引用(T&&)是实现移动语义的关键。它专门绑定右值(临时对象),通过'窃取'资源而非深拷贝来提升性能,这与左值引用(T&)有本质区别。
面向对象核心(OOP)
类与对象的封装细节
封装不仅是将成员私有化,更要在 setter 中加入数据校验逻辑。静态成员属于类本身,所有对象共享,静态成员函数没有 this 指针。
友元关系(函数或类)可访问私有成员,但不可传递和继承。关于类的大小计算,遵循内存对齐原则。空类大小为 1 字节,静态成员和成员函数不占用实例大小。
构造与析构的生命周期管理
委托构造(C++11)允许一个构造函数调用另一个,减少冗余。显式构造函数(explicit)禁止隐式类型转换,防止意外行为。
拷贝构造函数在对象值传递、返回或初始化时调用。若类中有指针成员,必须手动实现深拷贝,否则默认浅拷贝会导致重复释放。移动构造函数(Class(Class&& other))则用于窃取资源,提升效率,通常需将源对象指针置空。
析构函数不能重载,可以是纯虚函数但必须有实现。析构顺序遵循逆序原则。内存泄漏常发生在构造函数分配堆内存却未在析构中释放,或异常导致析构中断,RAII 机制可有效解决此问题。
继承与派生规则
继承方式决定了权限映射:public 继承保持 public/protected,private 继承将所有基类成员变为 private。赋值兼容规则允许向上转型(派生给基类),向下转型则不安全,需用 dynamic_cast。
虚基类通过添加虚基类指针确保最终派生类只保留一份基类成员。同名成员会隐藏基类成员,需加作用域符访问。同名的成员函数不构成重载,因为属于不同作用域。
多态性与运算符重载
静态多态体现于模板特化和函数重载决议。动态多态依赖虚函数表(vtable)和虚表指针(vptr)。通过基类指针调用虚函数时,运行时根据 vptr 找到实际函数地址。

