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"关系
- 多态会增加一定的运行时开销(虚函数表查找)
- 构造函数和析构函数中不要调用虚函数,此时多态机制不会正常工作
- 使用智能指针管理多态对象可以避免内存泄漏问题
