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

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

综述由AI生成C++ 继承是面向对象编程实现代码复用的关键机制。详细阐述了继承的基本语法、三种访问权限控制方式(public/protected/private)以及构造析构函数的调用顺序。通过 Person/Student 及员工管理系统的实战案例,演示了如何正确设计基类与派生类,解决多重继承二义性问题,并提供了常见错误排查方案,帮助开发者掌握继承的核心原理与应用技巧。

暖阳发布于 2026/3/22更新于 2026/5/45 浏览
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

运行结果如下:

张三 正在吃饭
张三 正在睡觉
张三 正在学习,学号: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 继承演示
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>
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;
}

运行结果:

Person 基类构造函数被调用
Student 派生类构造函数被调用
Student 派生类析构函数被调用
Person 基类析构函数被调用
4.3 带参数的构造函数继承

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

#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;
}

运行结果:

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

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

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

更多推荐文章

查看全部
  • 网络带宽和质量测试工具iPerf3 使用指南
  • C++ 容器详解:std::list 与 std::forward_list 对比分析
  • VSCode 集成 GitHub Copilot 安装与使用指南
  • VSCode 中 GitHub Copilot 安装与实战指南
  • Java Map 核心实现与常用方法详解
  • 2024 年中国 AI+ 营销趋势洞察与企业落地建议报告
  • GitHub Copilot 中配置并使用 MCP 服务指南
  • DeepSeek 20 个实用建议:普通人如何高效使用大模型
  • Unity Shader Graph Triplanar 节点原理解析与实战
  • Kiro 安装与使用指南:AWS 新一代 AI IDE 两种部署方式
  • 2026 年 Python+AI 学习路线:从零基础到实战
  • 基于 C++ 的 x86 虚拟化抽象框架设计与实现
  • Flutter 与 Web 混合开发实战指南
  • ESP32 开发板搭建同步 WebServer 服务
  • OpenClaw 大龙虾机器人本地部署与配置实战
  • 线性 DP 经典四题详解:台阶、子段和、传球与乌龟棋
  • 数据结构:顺序表与链表经典算法实战
  • 算法空间复杂度详解:概念与计算实例
  • 计算机视觉基础与实战应用指南
  • JavaScript 直连 MongoDB 实战指南与避坑手册

相关免费在线工具

  • 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