面向对象
C++ 的面向对象建立在「类」之上,通过继承与虚函数实现多态。掌握默认生成的特殊成员函数与访问控制,是写出安全类的关键。
类与对象
类是用户定义的类型,封装数据与操作。class 默认私有继承,struct 默认公有,二者语法几乎相同。成员函数可以在类内定义(隐式 inline)或在类外用 :: 定义。
struct Point {
double x;
double y;
double distance() const { return std::sqrt(x*x + y*y); }
};
C++11 起可在类内为成员提供默认值,推荐用花括号或 = 初始化。
构造函数与析构函数
构造函数用于初始化对象,析构函数用于释放资源。遵循 RAII(Resource Acquisition Is Initialization)原则:构造函数获取资源,析构函数释放。
- 默认构造函数:
T() - 拷贝构造函数:
T(const T&) - 移动构造函数:
T(T&&)(C++11) - 拷贝赋值与移动赋值运算符
- 析构函数:
~T()
编译器在多数情况下会按需生成以上函数,= default 显式要求生成,= delete 显式禁用。
继承
继承表达「is-a」关系。public 继承保留父类对外接口,protected 与 private 继承则收紧可见性。final 关键字可禁止进一步继承或重写。
class Shape {
public:
virtual double area() const = 0; // 纯虚函数
virtual ~Shape() = default; // 虚析构,基类必备
};
class Circle : public Shape {
double r;
public:
explicit Circle(double radius) : r(radius) {}
double area() const override { return 3.14159 * r * r; }
};
派生类构造时先调用基类构造,析构顺序相反。
虚函数与多态
用基类指针或引用调用虚函数时,实际执行的是派生类版本,这就是运行时多态。override 标记帮助编译器检查签名是否匹配父类。含有虚函数的类应将析构函数也声明为 virtual,避免通过基类指针删除时只析构基类部分。
访问控制与 this 指针
public、protected、private 控制成员的可见性。成员函数内部可用 this 指针访问当前对象,*this 表示当前对象的引用。mutable 关键字允许在 const 成员函数中修改成员,常用于互斥锁或缓存。