C++: 继承基础

最后更新:2026-08-26

假设你写了 Student 类和 Teacher 类,发现它们都有姓名、年龄,但学生有学号,老师有工号。

能不能复用 Person 类的代码?继承就是干这个的——让类之间形成"父子"关系。


1. 什么是继承?

(1) 1.1 生活中的继承

生活场景 程序中的对应
孩子继承父母的特征(眼睛颜色、身高等) 派生类继承基类的成员
孩子可以有自己的特征(如特长) 派生类可以添加新成员

继承的本质: 在已有类的基础上,扩展出新类。

(2) 1.2 为什么需要继承?

不用继承(重复代码):

▶ 示例 2:代码示例(难度⭐)

CPP
#include <iostream>
#include <string>

// 学生类
class Student {
 std::string name;
 int age;
 std::string studentId;
};

// 老师类
class Teacher {
 std::string name; // ❌ 重复了
 int age; // ❌ 重复了
 std::string teacherId;
};
▶ 试一试

输出:

TEXT 📖 仅展示
(程序输出)

用继承(代码复用):

CPP
#include <iostream>
#include <string>

// 基类(父类)
class Person {
public:
 std::string name;
 int age;
};

// 派生类(子类)
class Student : public Person {
public:
 std::string studentId; // 新增成员
};

class Teacher : public Person {
public:
 std::string teacherId; // 新增成员
};


2. 继承的基本语法

(1) 2.1 声明派生类

语法:

CPP
class DerivedClassName : inheritanceMode BaseClassName {
 // new members
};

示例:

CPP
#include <iostream>
#include <string>

class Person {
public:
 std::string name;
 int age;
};

// Student 继承 Person
class Student : public Person {
public:
 std::string studentId;
};

int main() {
 Student s1;
 s1.name = "Alice"; // ✅ 继承了 name
 s1.age = 20; // ✅ 继承了 age
 s1.studentId = "2024001"; // 自己的成员
 
 std::cout << "姓名:" << s1.name << std::endl;
 std::cout << "年龄:" << s1.age << std::endl;
 std::cout << "学号:" << s1.studentId << std::endl;
 
 return 0;
}


3. 继承方式(访问控制)

(1) 3.1 三种继承方式

基类成员 \ 继承方式 public 继承 protected 继承 private 继承
public 成员 public(不变) protected private
protected 成员 protected protected private
private 成员 不可访问 不可访问 不可访问

💡 重点: 最常用的继承方式是 public 继承。

(2) 3.2 public 继承(推荐)

CPP
#include <iostream>
#include <string>

class Person {
private:
 std::string id; // 私有成员:派生类不可访问
 
protected:
 std::string address; // 保护成员:派生类可访问
 
public:
 std::string name; // 公有成员:大家都能访问
 
 void introduce() {
 std::cout << "我叫 " << name << std::endl;
 }
};

class Student : public Person {
public:
 void setAddress(const std::string& addr) {
 address = addr; // ✅ 可以访问保护成员
 // id = "123"; // ❌ 不可访问私有成员
 }
};

int main() {
 Student s1;
 s1.name = "Alice"; // ✅ 可以访问
 // s1.address = "Wuhan"; // ❌ 不可访问(protected)
 
 return 0;
}


4. 构造函数与继承

(1) 4.1 派生类构造函数的调用顺序

规则: 先调用基类构造函数,再调用派生类构造函数

CPP
#include <iostream>
#include <string>

class Person {
public:
 Person() {
 std::cout << "Person 构造函数" << std::endl;
 }
};

class Student : public Person {
public:
 Student() {
 std::cout << "Student 构造函数" << std::endl;
 }
};

int main() {
 Student s1;
 return 0;
}

💡 重点: 析构函数的调用顺序相反——先调用派生类析构函数,再调用基类析构函数。



5. 实战:简单的学生管理系统(继承版)

▶ 示例 1:用继承实现(难度⭐⭐)

CPP
#include <iostream>
#include <string>

// 基类
class Person {
protected:
 std::string name;
 int age;
 
public:
 Person(const std::string& n, int a) : name(n), age(a) {}
 
 void introduce() {
 std::cout << "姓名:" << name << ",年龄:" << age << std::endl;
 }
};

// 派生类:学生
class Student : public Person {
private:
 std::string studentId;
 double score;
 
public:
 Student(const std::string& n, int a, const std::string& id, double s)
 : Person(n, a), studentId(id), score(s) {}
 
 void introduce() {
 Person::introduce(); // 调用基类的 introduce
 std::cout << "学号:" << studentId << ",成绩:" << score << std::endl;
 }
};

int main() {
 Student s1("Alice", 20, "2024001", 92.5);
 s1.introduce();
 
 return 0;
}
▶ 试一试

输出:

TEXT 📖 仅展示
姓名:Alice,年龄:20
学号:2024001,成绩:92.5

❓ 常见问题

Q 继承方式有哪些?应该用哪个?
A > - public 继承:最常用,保持基类的接口不变 > - protected 继承:不常用 > - private 继承:不常用

▶ 示例 3:派生类构造函数(难度⭐)

CPP
#include <iostream>
#include <string>

class Animal {
protected:
    std::string name;
public:
    Animal(std::string n) : name(n) {}
    void speak() { std::cout << name << "发出声音" << std::endl; }
};

class Dog : public Animal {
public:
    Dog(std::string n) : Animal(n) {}
    void speak() { std::cout << name << "汪汪叫" << std::endl; }
};

int main() {
    Dog dog("旺财");
    dog.speak();

    return 0;
}
▶ 试一试

输出:

TEXT 📖 仅展示
旺财汪汪叫
💡 提示:派生类构造函数需要调用基类构造函数初始化基类成员。派生类可以重写基类的成员函数。


📖 小节


📝 作业

  1. 基础题 (Difficulty ⭐): 定义一个 Animal 基类,包含 name 成员。让 DogCat 类继承它。

  2. 进阶题 (Difficulty ⭐⭐): 扩展上面的程序,给 Animal 添加 void speak() 虚函数(后面会学),让 DogCat 重写它。

  3. 挑战题 (Difficulty ⭐⭐⭐): 设计一个图书馆管理系统的类层次结构:

  4. Person(姓名、年龄)

  5. Student 继承 Person(学号、借阅数量)

  6. Teacher 继承 Person(工号、借阅数量)

  7. 实现借阅和归还功能。

  8. 继承:派生类拥有基类的所有成员

  1. 派生类构造函数调用基类构造函数
  2. is-a 关系:派生类是基类的一种

6. 🚀 下一步

学会了继承基础,接下来我们学习 多态(第32课)—— 让基类指针能调用派生类的函数,实现"一个接口,多种实现"!

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏