引言在面向对象编程中继承是三大核心特性封装、继承、多态之一。它允许我们基于已有的类创建新的类从而实现代码复用和层次化设计。在我学习 C 的过程中继承这个概念一开始让我感到抽象——什么是基类什么是派生类继承方式有什么区别今天我将通过简洁的示例带你快速理解继承与派生的核心知识。第一部分继承的基本概念一、什么是继承继承允许我们创建一个新类派生类来吸收另一个已存在类基类的成员。// 基类父类被继承的类 class Person { // 成员... }; // 派生类子类继承基类的类 class Student : public Person { // 新增成员... };二、为什么需要继承// 不使用继承代码重复 class Person { int id; string name; public: void setId(int i) { id i; } void setName(string n) { name n; } void show() { cout name ( id ) endl; } }; class Student { int id; string name; float score; // 学生特有的成绩 public: void setId(int i) { id i; } void setName(string n) { name n; } void setScore(float s) { score s; } void show() { cout name ( id ), score: score endl; } }; // 问题Person 和 Student 有大量重复代码// 使用继承代码复用 class Person { int id; string name; public: Person(int i, string n) : id(i), name(n) {} void setId(int i) { id i; } void setName(string n) { name n; } void show() { cout name ( id ) endl; } }; // Student 继承 Person自动拥有 id、name 及相关方法 class Student : public Person { float score; public: Student(int i, string n, float s) : Person(i, n), score(s) {} void setScore(float s) { score s; } void show() { Person::show(); // 调用基类的 show cout score: score endl; } };第二部分三种继承方式C 提供了三种继承方式public、protected、private。它们控制着基类成员在派生类中的访问权限。一、继承方式总览基类成员访问限定public 继承protected 继承private 继承public 成员→ public→ protected→ privateprotected 成员→ protected→ protected→ privateprivate 成员不可访问不可访问不可访问二、图解继承方式三、代码示例class Person { private: int pid; string name; protected: void setPid(int id) { pid id; } void setName(string n) { name n; } public: Person(int id, string n) : pid(id), name(n) {} void eat() { cout name is eating endl; } void sleep() { cout name is sleeping endl; } void show() { cout name ( pid ) endl; } }; // 1. public 继承最常用 class StudentPublic : public Person { public: StudentPublic(int id, string n) : Person(id, n) {} void study() { // 可以访问 protected 成员 setPid(100); setName(张三); // 可以访问 public 成员 eat(); sleep(); // ❌ 不能访问 private 成员 // pid 100; // 错误 // name 李四; // 错误 } }; // 2. protected 继承 class StudentProtected : protected Person { public: StudentProtected(int id, string n) : Person(id, n) {} void study() { // 派生类内部protected 成员仍可访问 setPid(100); setName(李四); eat(); // 在派生类内部public → protected仍可访问 sleep(); } }; // 3. private 继承 class StudentPrivate : private Person { public: StudentPrivate(int id, string n) : Person(id, n) {} void study() { // 派生类内部所有非 private 成员仍可访问 setPid(100); setName(王五); eat(); sleep(); } }; int main() { // public 继承对象可以访问 public 成员 StudentPublic sp(1, 张三); sp.eat(); // ✅ 可以 sp.sleep(); // ✅ 可以 // sp.setPid(2); // ❌ 错误protected 成员不可访问 // protected 继承对象不能访问任何基类成员 StudentProtected sp2(2, 李四); // sp2.eat(); // ❌ 错误eat 变成了 protected // private 继承对象不能访问任何基类成员 StudentPrivate sp3(3, 王五); // sp3.eat(); // ❌ 错误eat 变成了 private return 0; }第三部分派生类的构造函数一、构造函数的调用顺序重要规则派生类的构造函数默认会调用基类的无参构造函数class Person { private: int pid; string name; public: // 无参构造函数 Person() { cout Person 无参构造函数 endl; pid 0; name ; } // 有参构造函数 Person(int id, string n) : pid(id), name(n) { cout Person 有参构造函数 endl; } }; class Student : public Person { private: float score; public: // 没有显式调用基类构造函数 → 默认调用 Person() Student(float s) : score(s) { cout Student 构造函数 endl; } // 显式调用基类有参构造函数 Student(int id, string n, float s) : Person(id, n), score(s) { cout Student 有参构造函数 endl; } }; int main() { cout 创建 s1 endl; Student s1(90); // 调用 Person() Student(float) cout \n 创建 s2 endl; Student s2(1001, 张三, 95); // 调用 Person(int,string) Student(...) return 0; } /* 输出 创建 s1 Person 无参构造函数 Student 构造函数 创建 s2 Person 有参构造函数 Student 有参构造函数 */二、构造函数的调用顺序总结第四部分完整示例——Student 继承 Person#include iostream #include string using namespace std; class Person { private: int pid; // 私有成员派生类无法直接访问 string name; protected: // 受保护成员派生类可以访问 void setPid(int id) { pid id; } void setName(string n) { name n; } public: Person(int id, string n) : pid(id), name(n) { cout Person 构造函数: name endl; } void hi() { cout Hello, Im name (ID: pid ) endl; } ~Person() { cout Person 析构函数: name endl; } }; class Student : public Person { private: float score; // 学生特有的成绩 public: // 在初始化列表上指定基类的构造函数 Student(int pid, string name, float score) : Person(pid, name) { // 调用基类构造函数 this-score score; cout Student 构造函数: score score endl; } // 通过 protected 成员修改基类数据 void updatePidAndName(int pid, string name) { setPid(pid); // 调用基类的 protected 方法 setName(name); // 调用基类的 protected 方法 } // 重定义隐藏基类的 hi 函数 void hi() { Person::hi(); // 调用基类的 hi cout My score is score endl; } ~Student() { cout Student 析构函数: score score endl; } }; int main() { cout 创建学生 s1 endl; Student s1(1001, 李刚, 900); cout \n 调用 hi() endl; s1.hi(); cout \n 修改信息 endl; s1.updatePidAndName(1003, 王刚); cout \n 再次调用 hi() endl; s1.hi(); cout \n 程序结束 endl; return 0; } /* 输出 创建学生 s1 Person 构造函数: 李刚 Student 构造函数: score900 调用 hi() Hello, Im 李刚 (ID: 1001) My score is 900 修改信息 再次调用 hi() Hello, Im 王刚 (ID: 1003) My score is 900 程序结束 Student 析构函数: score900 Person 析构函数: 王刚 */第五部分关键知识点总结一、继承方式速查表继承方式基类 public基类 protected基类 private派生类对象访问publicpublicprotected不可访问✅ 可访问 publicprotectedprotectedprotected不可访问❌ 不可访问privateprivateprivate不可访问❌ 不可访问二、派生类内部访问规则class Base { private: int a; // 派生类不可访问 protected: int b; // 派生类可以访问 public: int c; // 派生类可以访问 }; class Derived : public Base { void func() { // a 1; // ❌ 错误不能访问 private b 2; // ✅ 可以访问 protected c 3; // ✅ 可以访问 public } };三、构造函数调用规则情况行为派生类不写构造函数编译器生成默认构造函数调用基类默认构造派生类写了构造函数未指定基类构造默认调用基类无参构造函数基类没有无参构造函数派生类必须在初始化列表中显式调用基类有参构造继承是 C 面向对象编程的核心特性之一。本文介绍了继承的基础知识三种继承方式public最常用、protected、private构造函数的调用顺序先基类后派生类访问权限派生类可以访问基类的 public 和 protected 成员实用建议日常开发中99% 的情况使用 public 继承protected 继承和 private 继承使用较少主要在特殊场景如实现组合关系如果基类没有无参构造函数派生类必须在初始化列表中显式调用基类构造函数下一篇我们将深入讲解继承中的构造函数与析构函数详解多重继承与菱形继承问题虚继承的解决方案运行时多态与虚函数