跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++

C++ 继承:面向对象的代码复用核心机制

综述由AI生成C++ 继承的核心概念、语法及三种访问权限控制方式(public/protected/private)。详细阐述了基类与派生类的构造与析构顺序规则,并通过员工管理系统案例演示了实际应用场景。最后总结了多重继承的二义性解决方案及常见问题处理技巧,旨在帮助开发者掌握面向对象代码复用的关键机制。

ApiHolic发布于 2026/3/30更新于 2026/5/2423 浏览
C++ 继承:面向对象的代码复用核心机制

C++ 继承:面向对象的代码复用核心机制

在这里插入图片描述

💡 学习目标:掌握继承的基本语法与核心特性,理解不同继承方式的访问权限控制,能够通过继承实现代码复用与扩展。 💡 学习重点:继承的语法格式、三种继承方式的区别、基类与派生类的关系、继承中的构造与析构顺序。

一、继承的概念与核心价值

✅ 结论:继承是 C++ 面向对象三大特性之一,允许一个类派生类继承另一个类基类的属性和行为,实现代码复用,同时支持派生类在基类基础上扩展新功能。

继承的核心价值体现在两个方面:

  1. 代码复用:避免重复编写相同的成员变量和成员函数,降低代码冗余度
  2. 功能扩展:派生类可以在基类的基础上新增属性和方法,满足更复杂的业务需求

生活中的继承示例:学生和老师都属于'人',都有姓名、年龄等属性和吃饭、睡觉等行为。可以先定义 Person 基类,再让 Student 和 Teacher 继承 Person,并各自扩展专属功能。

二、继承的基本语法与实现

2.1 继承的语法格式
class 派生类名 : 继承方式 基类名 {
    // 派生类的成员
};
  • 继承方式:决定基类成员在派生类中的访问权限,包括 public、protected、private 三种
  • 基类名:被继承的类,也叫父类或超类
  • 派生类名:继承基类的类,也叫子类或衍生类
2.2 继承的基础实现案例

💡 以 Person 作为基类,Student 作为派生类为例,演示继承的基本用法

#include <iostream>
#include <string>
using namespace std;

// 基类:人
class Person {
public:
    string name;
    int age;
    void eat() {
        cout << name << " 正在吃饭" << endl;
    }
    void sleep() {
        cout << name << " 正在睡觉" << endl;
    }
};

// 派生类:学生,公有继承 Person
class Student : public Person {
public:
    // 派生类新增属性:学号
    int studentID;
    // 派生类新增方法:学习
    void study() {
        cout << name << " 正在学习,学号:" << studentID << endl;
    }
};

int main() {
    // 创建派生类对象 Student s
    // 访问从基类继承的属性
    s.name = "张三";
    s.age = 18;
    // 访问派生类自身的属性
    s.studentID = 2024001;
    // 调用从基类继承的方法
    s.eat();
    s.sleep();
    // 调用派生类自身的方法
    s.study();
    return 0;
}
2.3 运行结果
张三 正在吃饭 张三 正在睡觉 张三 正在学习,学号:2024001 

三、三种继承方式的访问权限控制

💡 继承方式直接影响基类成员在派生类中的访问权限,核心规则是继承方式不会提升成员的访问权限,只会限制或保持原有权限。

3.1 三种继承方式的权限对比表
基类成员权限public 继承protected 继承private 继承
publicpublicprotectedprivate
protectedprotectedprotectedprivate
private不可访问不可访问不可访问

⚠️ 核心注意点

  1. 基类的 private 成员在派生类中始终不可直接访问,只能通过基类的 public 或 protected 方法间接访问
  2. 继承方式的限制作用是单向的,派生类无法突破基类的权限限制
  3. 实际开发中,public 继承是最常用的方式,protected 和 private 继承仅在特定场景使用
3.2 不同继承方式的代码演示
3.2.1 public 继承演示
#include <iostream>
#include <string>
using namespace std;

class Base {
public:
    int pub;
protected:
    int pro;
private:
    int pri
};

// 公有继承
class PubDerived : public Base {
public:
    void show() {
        pub = 10;      // 合法:public 继承后仍为 public
        pro = 20;      // 合法:public 继承后为 protected
        // pri = 30;   // 非法:基类 private 成员不可访问
    }
};

int main() {
    PubDerived pd;
    pd.pub = 100;    // 合法:类外可访问 public 成员
    // pd.pro = 200; // 非法:protected 成员类外不可访问
    return 0;
}
3.2.2 protected 继承演示
class ProDerived : protected Base {
public:
    void show() {
        pub = 10;      // 合法:protected 继承后为 protected
        pro = 20;      // 合法:protected 继承后仍为 protected
        // pri = 30;   // 非法:基类 private 成员不可访问
    }
};

int main() {
    ProDerived prd;
    // prd.pub = 100; // 非法:protected 继承后 pub 变为 protected,类外不可访问
    return 0;
}
3.2.3 private 继承演示
class PriDerived : private Base {
public:
    void show() {
        pub = 10;      // 合法:private 继承后为 private
        pro = 20;      // 合法:private 继承后为 private
        // pri = 30;   // 非法:基类 private 成员不可访问
    }
};

int main() {
    PriDerived prd;
    // prd.pub = 100; // 非法:private 继承后 pub 变为 private,类外不可访问
    return 0;
}

四、继承中的构造与析构顺序

💡 派生类对象的创建和销毁过程,会涉及基类和派生类的构造函数、析构函数调用,其顺序有严格的规则。

4.1 核心规则

✅ 构造顺序:先调用基类的构造函数,再调用派生类的构造函数
✅ 析构顺序:先调用派生类的析构函数,再调用基类的析构函数
简单记忆:构造先基后派,析构先派后基

4.2 代码演示:构造与析构顺序
#include <iostream>
#include <string>
using namespace std;

class Person {
public:
    Person() {
        cout << "Person 基类构造函数被调用" << endl;
    }
    ~Person() {
        cout << "Person 基类析构函数被调用" << endl;
    }
};

class Student : public Person {
public:
    Student() {
        cout << "Student 派生类构造函数被调用" << endl;
    }
    ~Student() {
        cout << "Student 派生类析构函数被调用" << endl;
    }
};

int main() {
    // 创建派生类对象 Student s
    // 函数结束时对象销毁,自动调用析构函数
    return 0;
}
4.3 运行结果
Person 基类构造函数被调用 Student 派生类构造函数被调用 Student 派生类析构函数被调用 Person 基类析构函数被调用 
4.4 带参数的构造函数继承

当基类只有带参数的构造函数时,派生类必须在初始化列表中显式调用基类的构造函数。

#include <iostream>
#include <string>
using namespace std;

class Person {
public:
    string name;
    int age;
    // 基类带参数构造函数
    Person(string n, int a) {
        name = n;
        age = a;
        cout << "Person 带参构造函数被调用" << endl;
    }
};

class Student : public Person {
public:
    int studentID;
    // 派生类构造函数:初始化列表中调用基类构造
    Student(string n, int a, int id) : Person(n, a) {
        studentID = id;
        cout << "Student 带参构造函数被调用" << endl;
    }
    void show() {
        cout << "姓名:" << name << " 年龄:" << age << " 学号:" << studentID << endl;
    }
};

int main() {
    Student s("李四", 20, 2024002);
    s.show();
    return 0;
}

五、继承的实战案例:员工管理系统

💡 需求:设计一个简单的员工管理系统,包含普通员工 Employee 和经理 Manager 两类角色。Employee 包含姓名、工号、工资属性和工作方法;Manager 继承 Employee,并新增部门属性和管理方法。

5.1 需求分析
  1. 基类 Employee:属性(姓名、工号、工资),方法(工作 work())
  2. 派生类 Manager:公有继承 Employee,新增属性(部门),新增方法(管理 manage())
  3. 要求通过构造函数初始化所有属性,保证数据完整性
5.2 完整代码实现
#include <iostream>
#include <string>
using namespace std;

// 基类:普通员工
class Employee {
protected:
    string name;
    int empID;
    double salary;
public:
    // 带参构造函数
    Employee(string n, int id, double sal) {
        name = n;
        empID = id;
        salary = sal;
        cout << "Employee 构造函数被调用" << endl;
    }
    // 工作方法
    void work() {
        cout << "员工 " << name << "(工号:" << empID << ")正在工作,月薪:" << salary << endl;
    }
    ~Employee() {
        cout << "Employee 析构函数被调用" << endl;
    }
};

// 派生类:经理,公有继承普通员工
class Manager : public Employee {
private:
    // 新增属性:管理部门
    string department;
public:
    // 构造函数:初始化列表调用基类构造
    Manager(string n, int id, double sal, string dep) : Employee(n, id, sal) {
        department = dep;
        cout << "Manager 构造函数被调用" << endl;
    }
    // 新增方法:管理
    void manage() {
        cout << "经理 " << name << " 管理 " << department << " 部门" << endl;
    }
    // 重写基类的 work 方法(方法重写)
    void work() {
        cout << "经理 " << name << "(工号:" << empID << ")正在管理工作,月薪:" << salary << endl;
    }
    ~Manager() {
        cout << "Manager 析构函数被调用" << endl;
    }
};

int main() {
    // 创建普通员工对象 Employee emp
    Employee emp("王五", 1001, 5000.0);
    emp.work();
    cout << "-------------------------" << endl;
    // 创建经理对象 Manager mgr
    Manager mgr("赵六", 9001, 15000.0, "技术部");
    mgr.work();       // 调用重写后的 work 方法
    mgr.manage();     // 调用新增的 manage 方法
    return 0;
}
5.3 运行结果
Employee 构造函数被调用 员工 王五(工号:1001)正在工作,月薪:5000 ------------------------- Employee 构造函数被调用 Manager 构造函数被调用 经理 赵六(工号:9001)正在管理工作,月薪:15000 经理 赵六 管理 技术部 部门 Manager 析构函数被调用 Employee 析构函数被调用 Employee 析构函数被调用 

六、继承的常见问题与解决方案

6.1 问题 1:派生类无法访问基类 private 成员

解决方案:

  1. 将基类需要被派生类访问的成员设置为 protected 权限
  2. 在基类中提供 public 的 get/set 方法,让派生类间接访问 private 成员
6.2 问题 2:基类无默认构造函数,派生类编译报错

解决方案:
在派生类的构造函数初始化列表中,显式调用基类的带参数构造函数

6.3 问题 3:多重继承导致的二义性(钻石问题)

💡 多重继承是指一个派生类同时继承多个基类,容易出现同名成员冲突的问题。
解决方案:
使用作用域解析符 :: 明确指定要访问的基类成员

class A {
public:
    void func() {
        cout << "A 的 func 方法" << endl;
    }
};
class B {
public:
    void func() {
        cout << "B 的 func 方法" << endl;
    }
};
class C : public A, public B {};

int main() {
    C c;
    c.A::func(); // 明确调用 A 类的 func 方法
    c.B::func(); // 明确调用 B 类的 func 方法
    return 0;
}

七、本章总结

✅ 继承的核心是代码复用与功能扩展,派生类可以继承基类的属性和方法,并新增自己的专属内容。
✅ 三种继承方式中,public 继承最常用,其权限规则是'不提升、只限制'。
✅ 继承中的构造顺序是先基后派,析构顺序是先派后基,带参构造需要在初始化列表显式调用。
✅ 多重继承容易引发二义性,可通过作用域解析符解决,实际开发中应谨慎使用多重继承。

目录

  1. C++ 继承:面向对象的代码复用核心机制
  2. 一、继承的概念与核心价值
  3. 二、继承的基本语法与实现
  4. 2.1 继承的语法格式
  5. 2.2 继承的基础实现案例
  6. 2.3 运行结果
  7. 三、三种继承方式的访问权限控制
  8. 3.1 三种继承方式的权限对比表
  9. 3.2 不同继承方式的代码演示
  10. 3.2.1 public 继承演示
  11. 3.2.2 protected 继承演示
  12. 3.2.3 private 继承演示
  13. 四、继承中的构造与析构顺序
  14. 4.1 核心规则
  15. 4.2 代码演示:构造与析构顺序
  16. 4.3 运行结果
  17. 4.4 带参数的构造函数继承
  18. 五、继承的实战案例:员工管理系统
  19. 5.1 需求分析
  20. 5.2 完整代码实现
  21. 5.3 运行结果
  22. 六、继承的常见问题与解决方案
  23. 6.1 问题 1:派生类无法访问基类 private 成员
  24. 6.2 问题 2:基类无默认构造函数,派生类编译报错
  25. 6.3 问题 3:多重继承导致的二义性(钻石问题)
  26. 七、本章总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • C++ 继承:面向对象代码复用的核心机制
  • Git 基础命令与操作详解
  • AI 安全:Stable Diffusion 视觉提示词注入攻击原理与实现
  • LangChain Agent 实战:使用框架构建数学计算助手
  • C++26 契约编程概览与工程实践
  • 低代码AI架构:让灵活智能架构落地更简单
  • 离线部署 ChatGLM3 大模型实现本地 AI 聊天
  • 数据结构复习:Java 顺序表与 ArrayList 详解
  • 零基础转行 Python 核心知识体系与学习路径
  • Kafka 事务:构建可靠的分布式消息处理系统
  • 树莓派 Python 音频播放开发实战指南
  • 数据结构初阶:时间复杂度与空间复杂度计算
  • 数据结构初阶:树的概念、术语与表示方法
  • Rust 异步 Web 框架 Axum 的深入原理与高级用法
  • 开源模型全景图:如何选择你的技术底座
  • 贝叶斯网络原理与代码实战
  • DooTask 接入 AI 重塑项目管理效率新标杆
  • Qwen3-VL WebUI 详解:支持视频理解与 GUI 操作
  • Moltbot 集成飞书机器人
  • OpenClaw 对接腾讯 QQ 实战部署指南

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online