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

C++ 面向对象核心:深入理解继承机制

综述由AI生成继承是 C++ 面向对象编程实现代码复用的关键机制。通过定义基类和派生类,可以将公共属性和行为提取到基类中,减少冗余。本文详细讲解了继承的定义格式、三种继承方式(public/protected/private)对成员访问权限的影响,以及基类私有成员在派生类中的不可见性。此外,还涵盖了模板继承的典型应用如 stack 基于 vector 的实现,以及派生类与基类之间的类型转换规则,包括向上转换的安全性和向下转换的注意事项。

2177283801发布于 2025/9/16更新于 2026/6/715 浏览
C++ 面向对象核心:深入理解继承机制

继承概述

继承(Inheritance)是 C++ 面向对象程序设计实现代码复用的最重要手段。它允许我们在保持原有类特性的基础上进行扩展,增加新的方法(成员函数)和属性(成员变量),从而产生新的类,称为派生类。

为什么需要继承?

想象一下,如果我们要定义 Student 和 Teacher 两个类。这两个类里面都有姓名、地址、年龄、电话等成员变量,都有身份认证的成员函数。如果不使用继承,设计时就会出现大量冗余。

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

class Student {
public:
    // 进入校园/图书馆/实验室刷二维码等身份认证
    void identity() {
        cout << "Student Identity" << endl;
    }
    // 学习
    void study() {
        // ...
    }
protected:
    string _name = "peter"; // 姓名
    string _address; // 地址
    string _tel; // 电话
    int _age = 18; // 年龄
    int _stuid; // 学号
};

class Teacher {
public:
    void identity() {
        cout << "Teacher Identity" << endl;
    }
    // 授课
    void teaching() {
        //...
    }
protected:
    string _name = "张三"; // 姓名
    int _age = 18; // 年龄
    string _address; // 地址
    string _tel; // 电话
    string _title; // 职称
};

int main() {
    return 0;
}

为了避免重复定义,我们可以将公共的成员提取到一个 Person 基类中,让 Student 和 Teacher 都继承 Person。

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

class Person {
public:
    // 进入校园/图书馆/实验室刷二维码等身份认证
    void identity() {
        cout << "Identity: " << _name << endl;
    }
protected:
    string _name = "张三"; // 姓名
    string _address; // 地址
    string _tel; // 电话
    int _age = 18; // 年龄
};

class Student : public Person {
public:
    // 学习
    void study() {
        // ...
    }
protected:
    int _stuid; // 学号
};

class Teacher : public Person {
public:
    // 授课
    void teaching() {
        //...
    }
protected:
    string title; // 职称
};

int main() {
    Student s;
    Teacher t;
    s.identity();
    t.identity();
    return 0;
}

继承的定义与术语

在术语上,Person 被称为基类(Base Class)或父类,而 Student 和 Teacher 被称为派生类(Derived Class)或子类。这种命名差异主要源于翻译习惯,两者指代同一概念。

继承关系示意图

继承结构图

继承方式对访问权限的影响

继承方式决定了基类成员在派生类中的可见性。下表总结了不同继承方式下,基类成员的访问权限变化:

类成员/继承方式public 继承protected 继承private 继承
基类的 public 成员派生类的 public 成员派生类的 protected 成员派生类的 private 成员
基类的 protected 成员派生类的 protected 成员派生类的 protected 成员派生类的 private 成员
基类的 private 成员在派生类中不可见在派生类中不可见在派生类中不可见

关键点说明:

  1. 私有成员不可见:基类的 private 成员在派生类中无论以什么方式继承都是不可见的。这里的'不可见'是指语法限制,虽然它们物理上存在于派生类对象中,但无法直接访问。
  2. 保护成员的作用:如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为 protected。可以看出保护成员限定符是因继承才出现的特殊机制。
  3. 权限计算规则:总结表格可以发现,基类的其他成员在派生类的访问方式遵循最小值原则:Min(成员在基类的访问限定符,继承方式)。即 public > protected > private。
  4. 默认继承方式:使用关键字 class 时默认的继承方式是 private,使用 struct 时默认的继承方式是 public。不过为了代码清晰,建议显式写出继承方式。
  5. 实际运用:在实际开发中一般使用 public 继承,几乎很少使用 protected 或 private 继承。因为后两者继承下来的成员只能在派生类的类里面使用,实际扩展维护性不强。

模板继承示例

标准库中的容器往往也体现了继承的思想。例如 stack 和 vector 的关系,既符合 is-a 关系,也符合 has-a 关系。

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

namespace jiang {
    template<class T>
    class stack : public vector<T> {
    public:
        void push(const T& x) {
            // 基类是类模板时,需要指定作用域,否则编译报错
            // error C3861: 'push_back': 找不到标识符
            // 因为 stack<int>实例化时,也实例化了 vector<int>了
            // 但是模版是按需实例化,push_back 等成员函数未实例化,所以找不到
            vector<T>::push_back(x);
        }
        void pop() {
            vector<T>::pop_back();
        }
        const T& top() {
            return vector<T>::back();
        }
        bool empty() {
            return vector<T>::empty();
        }
    };
}

int main() {
    jiang::stack<int> st;
    st.push(1);
    st.push(2);
    st.push(3);
    while (!st.empty()) {
        cout << st.top() << " ";
        st.pop();
    }
    return 0;
}

基类和派生类之间的转换

在继承体系中,对象之间的赋值和转换有严格的规则:

  1. 向上转换(Upcasting):public 继承的派生类对象可以赋值给基类的指针或引用。有个形象的说法叫'切片'或者'切割',寓意把派生类中基类那部分切出来,基类指针或引用指向的是派生类中切出来的基类那部分。
  2. 向下转换(Downcasting):基类对象不能直接赋值给派生类对象。基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用,但必须是基类的指针指向派生类对象时才是安全的。这里基类如果是多态类型,可以使用 RTTI(Run-Time Type Information)的 dynamic_cast 来进行识别后进行安全转换。

类型转换示意图

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

class Person {
protected:
    string _name; // 姓名
    string _sex; // 性别
    int _age; // 年龄
};

class Student : public Person {
public:
    int _No; // 学号
};

int main() {
    Student sobj;
    // 1. 派生类对象可以赋值给基类的指针/引用
    Person* pp = &sobj;
    Person& rp = sobj;
    // 派生类对象赋值给基类的对象是通过调用基类的拷贝构造完成的
    Person pobj = sobj;
    
    // 2. 基类对象不能赋值给派生类对象,这里会编译报错
    // sobj = pobj; 
    
    return 0;
}

目录

  1. 继承概述
  2. 为什么需要继承?
  3. 继承的定义与术语
  4. 继承方式对访问权限的影响
  5. 模板继承示例
  6. 基类和派生类之间的转换
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • 播客转多平台内容矩阵全自动化实战:OpenAI Whisper + Claude
  • 树莓派 Python PWM 控制 LED 亮度教程
  • Android 12 性能优化实战:解决崩溃、续航与卡顿问题
  • C++ STL 优先队列(priority_queue)原理与模拟实现
  • C#设计模式:工厂方法模式详解
  • AIGC 产品经理定义、职责及与 AI 产品经理的区别解析
  • C++ 语言基础与进阶教程
  • Windows 与 Ubuntu 双系统安装及 NVIDIA 驱动配置指南
  • VSCode 中 GitHub Copilot 的安装配置与高效用法
  • 下一代无障碍交互架构:Web MCP 微核多态与本地优先 SaaS 设计
  • C++ 继承:面向对象代码复用的核心机制
  • 火山引擎豆包大模型助力电商 AIGC 智能化升级
  • Chrome 插件开发指南:从 Web 到扩展及实战
  • 基于 Coze 工作流与 Sora2 的 AI 漫剧生成方法
  • Go Web 开发核心理论与实践
  • DFT 中的片上时钟控制器(OCC)架构设计与插入规则
  • macOS 使用中科大或清华镜像快速安装 Homebrew 教程
  • 机器人 DH 参数模型与正运动学
  • SimPO 大模型对齐算法原理与 ms-swift 实践
  • AI Agent 开发工程师技能体系与实战指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • 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