C++ 继承与多态
一、继承 (Inheritance)
1. 基本概念
继承是面向对象编程的重要特性,允许一个类(派生类/子类)基于另一个类(基类/父类)来构建,继承其属性和方法。
2. 继承方式
class Base { // 基类成员 }; // 公有继承 class DerivedPublic : public Base { /*...*/ }; // 保护继承 class DerivedProtected : protected Base { /*...*/ }; // 私有继承 class DerivedPrivate : private Base { /*...*/ };
3. 继承中的访问控制
public | public | public |
protected | public | protected |
private | public | 不可访问 |
public | protected | protected |
protected | protected | protected |
private | protected | 不可访问 |
public | private | private |
protected | private | private |
private | private | 不可访问 |
4. 继承中的构造函数与析构函数
- 构造顺序:基类 → 成员对象 → 派生类
- 析构顺序:派生类 → 成员对象 → 基类
二、多态 (Polymorphism)
1. 基本概念
多态是指通过基类的指针或引用调用派生类的重写函数的能力。
2. 虚函数 (Virtual Function)
class Base { public: virtual void show() { cout << "Base show" << endl; } virtual ~Base() {} // 虚析构函数 }; class Derived : public Base { public: void show() override { cout << "Derived show" << endl; } };
3. 纯虚函数与抽象类
class AbstractBase { public: virtual void pureVirtual() = 0; // 纯虚函数 }; class Concrete : public AbstractBase { public: void pureVirtual() override { /* 实现 */ } };
4. 多态的实现原理
- 虚函数表 (vtable):每个有虚函数的类都有一个虚函数表
- 虚指针 (vptr):每个对象包含一个指向虚函数表的指针
5. override 和 final 关键字
override
:显式指明重写基类虚函数final
:禁止派生类重写虚函数或禁止类被继承
三、继承与多态的应用示例
#include <iostream> using namespace std; class Shape { public: virtual double area() const = 0; // 纯虚函数 virtual ~Shape() {} }; class Circle : public Shape { double radius; public: Circle(double r) : radius(r) {} double area() const override { return 3.14159 * radius * radius; } }; class Rectangle : public Shape { double width, height; public: Rectangle(double w, double h) : width(w), height(h) {} double area() const override { return width * height; } }; void printArea(const Shape& shape) { cout << "Area: " << shape.area() << endl; } int main() { Circle c(5.0); Rectangle r(4.0, 6.0); printArea(c); // 输出圆的面积 printArea(r); // 输出矩形的面积 Shape* shapes[] = {&c, &r}; for (auto s : shapes) { cout << "Area: " << s->area() << endl; } return 0; }
四、注意事项
- 基类析构函数应该声明为虚函数,防止通过基类指针删除派生类对象时内存泄漏
- 不要滥用继承,遵循"is-a"关系
- 多态会增加一定的运行时开销(虚函数表查找)
- 构造函数和析构函数中不要调用虚函数,此时多态机制不会正常工作
- 使用智能指针管理多态对象可以避免内存泄漏问题