C++ 开发手册C++

CHAPTER 02表达层 · OOP

面向对象OOP

class、构造/析构、继承、多态、虚函数与 RAII。用对象封装状态与行为,用 RAII 把资源生命周期绑到作用域。

开始阅读难度入门先修第一章约2.5小时
02.1

类与对象

class 把数据(成员)与操作(方法)封装在一起。struct 与 class 几乎相同,仅默认访问权限不同(struct 默认 public)。

class Circle {
  double r_;
public:
  double area() const { return 3.14159 * r_ * r_; }
  void setRadius(double r) { r_ = r; }
};
02.2

构造与析构

构造函数初始化对象,析构函数在对象离开作用域/删除时调用。用成员初始化列表更高效(避免先默认构造再赋值)。

class Widget {
  int id_;
public:
  Widget(int id) : id_(id) {}     // 初始化列表
  ~Widget() { /* 清理 */ }
};
= default / = delete

可用 = default 让编译器生成默认实现,= delete 禁用拷贝(如唯一所有权对象),明确意图。

02.3

访问控制

public 对外接口、private 内部细节、protected 对子类可见。封装的核心是隐藏不变量的实现细节。

class Bank {
  double balance_ = 0;          // private 内部状态
public:
  void deposit(double a) { if (a > 0) balance_ += a; }
  double balance() const { return balance_; }
};
02.4

继承

继承表达"is-a"。派生类复用基类接口,: public Base 表示公有继承。基类析构函数应为 virtual(见多态)。

class Shape {
public:
  virtual double area() const = 0;   // 纯虚函数,抽象类
  virtual ~Shape() = default;
};
class Square : public Shape {
  double s_;
public:
  double area() const override { return s_ * s_; }
};
02.5

多态与虚函数

用基类指针/引用调用虚函数时,运行时按对象实际类型分派(动态绑定)。override 关键字让编译器检查是否真重写了基类虚函数。

void printArea(const Shape& s) {
  std::cout << s.area();   // 运行时按实际类型调用
}
Square sq{3};
printArea(sq);             // 输出 9
析构要 virtual

通过基类指针 delete 派生对象时,若基类析构非 virtual,只会调基类析构,导致派生部分泄漏。基类若要被继承,析构用 virtual。

02.6

组合优先

相比继承,"has-a"的组合更灵活、耦合更低。优先用成员对象组合行为,仅在确有"is-a"语义时继承。

class Engine { /* ... */ };
class Car {
  Engine engine_;   // 组合:Car has-an Engine
};
02.7

RAII

Resource Acquisition Is Initialization:资源在构造函数获取、析构函数释放,生命周期绑定到作用域,异常安全且不易泄漏。智能指针、锁、文件句柄都依此设计。

{
  std::ofstream f("a.txt");   // 构造即打开
  f << "hi";
}                              // 离开作用域自动关闭(析构)
异常安全

即使中间抛出异常,栈展开也会调用局部对象析构,RAII 保证资源被释放——这是 C++ 资源管理的中枢思想。

02.8

常见陷阱与 FAQ

什么时候该用 virtual 析构?

只要类可能被通过基类指针/引用析构(即被继承且有多态用法),基类析构就应为 virtual,否则派生部分不释放。

override 有什么用?
显式标注告诉编译器:这是重写。若基类没有对应的虚函数(签名不符),编译器会报错,避免"本想重写却变成重载/新函数"的隐蔽 bug。

继承还是组合?
能用组合表达就别继承。继承暴露基类内部、造成紧耦合;组合通过接口协作,更易测试与替换。

02.9

实战练习与资源

延伸资源