1. 类继承(Class Inheritance)
1.1 概述
类继承 是面向对象编程(OOP)中的一个核心概念,允许一个类(派生类)从另一个类(基类)继承属性和行为。通过继承,派生类可以重用基类的代码,并根据需要添加新的成员或重写现有成员。
1.2 语法
1  | class Base {  | 
1.3 代码示例
1  | 
  | 
1.4 执行结果
1  | Animal eats.  | 
2. 虚函数(Virtual Functions)
2.1 概述
虚函数 允许派生类重新定义基类中的函数,以实现多态性。在运行时,根据对象的实际类型调用相应的函数版本。
2.2 语法
1  | class Base {  | 
2.3 代码示例
1  | 
  | 
2.4 执行结果
1  | Drawing a circle.  | 
3. 纯虚类与抽象基类(Pure Virtual Classes and Abstract Base Classes)
3.1 概述
纯虚函数 是在基类中声明但不提供实现的虚函数。包含至少一个纯虚函数的类称为 抽象基类(Abstract Base Class,ABC)。抽象基类不能被实例化,要求派生类必须实现所有纯虚函数才能被实例化。
3.2 语法
1  | class Base {  | 
3.3 代码示例
1  | 
  | 
3.4 执行结果
1  | Car engine started.  | 
4. 继承后的访问控制(Access Control in Inheritance)
4.1 概述
继承时的 访问控制 决定了基类成员在派生类中的可访问性。继承方式主要有三种:public、protected 和 private。它们影响继承成员的访问级别。
4.2 语法与影响
- 公有继承(public inheritance):
- 基类的 
public成员在派生类中保持public。 - 基类的 
protected成员在派生类中保持protected。 - 基类的 
private成员在派生类中不可访问。 
 - 基类的 
 - 保护继承(protected inheritance):
- 基类的 
public和protected成员在派生类中都变为protected。 
 - 基类的 
 - 私有继承(private inheritance):
- 基类的 
public和protected成员在派生类中都变为private。 
 - 基类的 
 
4.3 代码示例
1  | 
  | 
5. 继承中类的作用域(Scope of Classes in Inheritance)
5.1 概述
在继承关系中,类的作用域决定了成员名称的可见性和访问方式。派生类可以访问基类的成员,根据访问控制的不同,还可能需要使用 作用域解析符 来访问隐藏的成员。
5.2 代码示例
1  | 
  | 
5.3 执行结果
1  | Display from Derived  | 
6. 构造函数与拷贝控制(Constructors and Copy Control in Inheritance)
6.1 概述
在继承体系中,类的构造函数和拷贝控制函数(拷贝构造函数、拷贝赋值运算符、析构函数)的调用顺序和行为需要注意。基类的构造函数在派生类之前调用,析构函数则在派生类之后调用。
6.2 构造函数的调用顺序
- 基类的 默认构造函数 首先被调用,除非派生类在初始化列表中显式调用其他基类构造函数。
 - 派生类的成员按照声明顺序被构造。
 - 派生类的构造函数体被执行。
 
6.3 代码示例
1  | 
  | 
6.4 执行结果
1  | Creating d1:  | 
7. 容器与继承(Containers and Inheritance)
7.1 概述
C++ 容器(如 std::vector、std::list 等) 通常存储对象的副本,而非指向对象的指针。因此,当与继承结合使用时,可能导致 切片(Object Slicing) 问题,即仅存储基类部分,丢失派生类特有的信息。为了实现多态性,推荐使用指针或智能指针存储对象。
7.2 切片问题示例
1  | 
  | 
7.3 使用指针避免切片
1  | 
  | 
7.5 智能指针选择
- **
std::unique_ptr**:- 独占所有权,不可复制,只能移动。
 - 适用于明确的单一所有权场景。
 
 - **
std::shared_ptr**:- 共享所有权,可以被多个指针共享和引用计数。
 - 适用于需要多个所有者的场景。
 
 
练习题目
1. 简单继承与成员访问
题目:
定义一个基类 Person,包含以下成员:
私有成员变量:
name(字符串类型),age(整数类型)公共成员函数
:
- 构造函数:接受姓名和年龄作为参数并初始化成员变量
 displayInfo():打印姓名和年龄
然后,定义一个派生类 Student,继承自 Person,并添加以下内容:
私有成员变量:
studentID(字符串类型)公共成员函数
:
- 构造函数:接受姓名、年龄和学号作为参数,并调用基类构造函数初始化姓名和年龄
 - 重写 
displayInfo():除了显示姓名和年龄外,还显示学号 
要求:
- 在 
main函数中,创建一个Student对象,并调用displayInfo()函数展示信息。 
示例输出:
1  | Name: Alice  | 
2. 虚函数重写与多态性
题目:
定义一个基类 Shape,包含以下内容:
公共成员函数
:
- 虚函数 
draw():在基类中实现,输出 “Drawing a generic shape.” 
- 虚函数 
 
然后,定义两个派生类 Circle 和 Rectangle,分别重写 draw() 函数,实现各自的输出:
Circle的draw()输出:”Drawing a circle.”Rectangle的draw()输出:”Drawing a rectangle.”
要求:
- 在 
main函数中,创建一个Shape类型的指针数组,包含不同类型的Shape对象(Circle和Rectangle)。 - 遍历数组,调用每个对象的 
draw()函数,验证多态性的实现。 
示例输出:
1  | Drawing a circle.  | 
3. 函数重载与隐藏
题目:
定义一个基类 Calculator,包含以下公共成员函数:
int add(int a, int b):返回两个整数的和double add(double a, double b):返回两个浮点数的和
然后,定义一个派生类 AdvancedCalculator,继承自 Calculator,并添加以下成员函数:
int add(int a, int b, int c):返回三个整数的和
要求:
在
1
main
函数中,创建一个
1
AdvancedCalculator
对象,分别调用以下函数,并观察输出:
add(2, 3)add(2.5, 3.5)add(1, 2, 3)
注意:
- 观察派生类中新增的 
add函数是否影响基类中的同名函数。 
示例输出:
1  | 5  | 
4. 抽象类与纯虚函数
题目:
定义一个抽象基类 Animal,包含以下内容:
公共纯虚函数
:
void makeSound() const:纯虚函数,用于发出动物的叫声
然后,定义两个派生类 Dog 和 Cat,分别实现 makeSound() 函数:
Dog的makeSound()输出:”Woof!”Cat的makeSound()输出:”Meow!”
要求:
- 在 
main函数中,创建Dog和Cat对象的基类指针,并调用makeSound()函数,展示多态性。 
示例输出:
1  | Woof!  | 
5. 构造函数与析构函数的继承
题目:
定义一个基类 Vehicle,包含以下内容:
公共成员函数
:
- 构造函数:输出 “Vehicle constructed.”
 - 析构函数:输出 “Vehicle destructed.”
 
然后,定义一个派生类 Car,继承自 Vehicle,并添加以下内容:
公共成员函数
:
- 构造函数:输出 “Car constructed.”
 - 析构函数:输出 “Car destructed.”
 
要求:
- 在 
main函数中,创建一个Car对象,并观察构造和析构的调用顺序。 
示例输出:
1  | Vehicle constructed.  |