跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C++

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

综述由AI生成C++ 继承是面向对象三大特性之一,允许派生类继承基类的属性和行为以实现代码复用和功能扩展。文章详细讲解了继承的基本语法格式,包括 public、protected 和 private 三种继承方式对成员访问权限的控制规则。重点阐述了派生类对象创建与销毁过程中基类和派生类构造与析构函数的调用顺序,即构造先基后派,析构先派后基。通过员工管理系统的实战案例演示了继承的具体应用,并针对派生类无法访问基类私有成员、基类无默认构造函数以及多重继承二义性等常见问题提供了解决方案。

剑仙发布于 2026/3/23更新于 2026/5/58 浏览
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 {
:
    
     studentID;
    
    { cout << name <<  << studentID << endl; }
};

{
    
    
    Student s;
    s.name = ;
    s.age = ;
    
    s.studentID = ;
    
    s.();
    s.();
    
    s.();
     ;
}
// 派生类:学生,公有继承 Person
class
Student
public
public
// 派生类新增属性:学号
int
// 派生类新增方法:学习
void study()
" 正在学习,学号:"
int main()
// 创建派生类对象 Student s
// 访问从基类继承的属性
"张三"
18
// 访问派生类自身的属性
2024001
// 调用从基类继承的方法
eat
sleep
// 调用派生类自身的方法
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>
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 继承演示
#include <iostream>
using namespace std;

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

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 继承演示
#include <iostream>
using namespace std;

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

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>
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
    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("王五", 1001, 5000.0);
    emp.work();
    cout << "-------------------------" << endl;
    // 创建经理对象
    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. 一、继承的概念与核心价值
  5. 二、继承的基本语法与实现
  6. 2.1 继承的语法格式
  7. 2.2 继承的基础实现案例
  8. 2.3 运行结果
  9. 三、三种继承方式的访问权限控制
  10. 3.1 三种继承方式的权限对比表
  11. 3.2 不同继承方式的代码演示
  12. 3.2.1 public 继承演示
  13. 3.2.2 protected 继承演示
  14. 3.2.3 private 继承演示
  15. 四、继承中的构造与析构顺序
  16. 4.1 核心规则
  17. 4.2 代码演示:构造与析构顺序
  18. 4.3 运行结果
  19. 4.4 带参数的构造函数继承
  20. 五、继承的实战案例:员工管理系统
  21. 5.1 需求分析
  22. 5.2 完整代码实现
  23. 5.3 运行结果
  24. 六、继承的常见问题与解决方案
  25. 6.1 问题 1:派生类无法访问基类 private 成员
  26. 6.2 问题 2:基类无默认构造函数,派生类编译报错
  27. 6.3 问题 3:多重继承导致的二义性(钻石问题)
  28. 七、本章总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • 中兴 5G 随身 WiFi 工具 UFI-Tools 隐私与更新控制修改指南
  • WebMCP:Chrome 新 API 特性与 Agentic Web 前瞻
  • AI 编程工具选型:Copilot、Cursor、Codex 核心差异
  • C++ 模板进阶:特化、萃取与可变参数模板
  • 大模型分布式训练与高效调参实战
  • 深入理解前端防抖与节流:原理、区别与实战示例
  • 基于 xxxwww 的电商爬虫系统实战与优化
  • C++ std::atomic 原子操作与无锁编程详解
  • Flutter 三方库 arcane_helper_utils 鸿蒙化适配指南
  • Lada v0.10.1 本地 AI 视频去马赛克工具使用指南
  • PowerShell Invoke-WebRequest 报错 Invalid URL 和 CommandNotFound 解决方案
  • Spring Web MVC 从入门到实战
  • JDK 版本切换与 SQL Server SSL 连接问题排查
  • FPGA 设计核心概念:扇出(Fan-out)详解与优化
  • 构建企业级 AI 大模型的关键步骤与框架
  • Python 3.12 logging 模块 LogRecord 详解
  • 基于大语言模型的智能爬虫 Crawlab AI 实践
  • Python 结合代理 IP 自动化采集音乐数据实战
  • 帆软填报报表控件联动实现方式
  • 前端数据库 IndexedDB 详解:构建离线 Web 应用

相关免费在线工具

  • 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