C++ 继承与派生知识点详解

一、 继承的基本概念

  1. 核心思想:继承是面向对象编程(OOP)的三大特性之一,允许派生类(子类) 复用基类(父类) 的属性和方法,同时可以扩展或修改原有功能,实现代码复用和层次化设计。
  2. 基类与派生类关系
  • 基类:被继承的类,包含通用的属性和方法。
  • 派生类:继承基类的类,可新增成员,也可重写基类成员。
  • 语法格式:
cpp 复制代码
class 派生类名 : 继承方式 基类名 {
    // 派生类成员
};

二、 三种继承方式

继承方式决定了基类成员在派生类中的访问权限,核心规则如下:

继承方式 基类公有成员 基类保护成员 基类私有成员 特点总结

public 公有继承 派生类公有 派生类保护 不可访问 基类公有/保护成员权限不变,私有成员始终不可直接访问

protected 保护继承 派生类保护 派生类保护 不可访问 基类公有成员降级为保护权限

private 私有继承 派生类私有 派生类私有 不可访问 基类公有/保护成员全部降级为私有权限

关键注意点:

  • 基类的 private 成员无论哪种继承方式,派生类都无法直接访问,只能通过基类的 public/protected 成员函数间接访问。
  • 继承方式默认为 private ( class 定义的类), struct 默认继承方式为 public 。

三、 派生类的构造与析构

派生类对象的创建和销毁遵循固定顺序,核心规则如下:

  1. 构造函数执行顺序
  • 先调用 基类的构造函数(若基类有多个构造函数,需在派生类构造函数初始化列表中指定)
  • 再调用 成员对象的构造函数(按成员对象在派生类中的声明顺序)
  • 最后调用 派生类自身的构造函数体
  • 语法示例:
cpp 复制代码
class Base {
public:
    Base(int a) : a(a) {} // 基类带参构造
private:
    int a;
};

class Derived : public Base {
public:
    // 派生类构造函数初始化列表:先基类,再成员对象,最后自身
    Derived(int a, int b) : Base(a), b(b) {}
private:
    int b;
};
 
  1. 析构函数执行顺序
  • 与构造顺序完全相反
  • 先调用 派生类析构函数体
  • 再调用 成员对象的析构函数
  • 最后调用 基类的析构函数

四、 成员的隐藏与重写

  1. 成员隐藏(同名覆盖)
  • 当派生类定义了与基类同名的成员变量或成员函数(参数列表可以不同),派生类成员会隐藏基类成员,直接访问时默认调用派生类成员。
  • 若要访问基类被隐藏的成员,需使用 基类名::成员名 显式指定。
  • 示例:
cpp 复制代码
class Base {
public:
    void show() { cout << "Base show" << endl; }
};

class Derived : public Base {
public:
    void show() { cout << "Derived show" << endl; } // 隐藏基类show
};

int main() {
    Derived d;
    d.show(); // 调用派生类show
    d.Base::show(); // 显式调用基类show
    return 0;
}
  1. 成员重写(覆盖,为多态做准备)
  • 派生类定义与基类同名、同参数列表、同返回值的虚函数,称为重写(override)。
  • 重写是实现多态的前提,与成员隐藏的核心区别是基类函数必须加 virtual 关键字。

五、 继承中的特殊情况

  1. 继承的访问控制延伸
  • 派生类的子类(孙子类)能否访问基类成员,取决于两层继承的方式。
  • 例如:基类 Base 公有继承给 Derived1 , Derived1 保护继承给 Derived2 ,则 Base 的公有成员在 Derived2 中为保护权限。
  1. 不可继承的成员
  • 基类的构造函数、析构函数、赋值运算符重载函数不能被继承,派生类需要自己定义(或使用编译器默认生成的)。
  • 基类的 static 成员可以被继承,属于整个类族共享,访问方式: 基类名::成员名 或 派生类名::成员名 。
  1. 菱形继承与二义性
  • 菱形继承:两个派生类继承同一个基类,又有一个类同时继承这两个派生类,导致基类成员在最终派生类中存在两份副本,引发访问二义性。
  • 解决方法:使用虚继承(在继承时加 virtual 关键字),让最终派生类只保留一份基类成员。
  • 虚继承语法:
cpp 复制代码
class A {};
class B : virtual public A {}; // 虚继承
class C : virtual public A {}; // 虚继承
class D : public B, public C {}; // 无二义性

六、 继承的优缺点

  1. 优点
  • 代码复用:减少重复代码,基类的通用功能只需编写一次。
  • 层次化设计:清晰体现类之间的从属关系(如 Animal → Dog → Husky ),符合现实逻辑。
  • 便于扩展:派生类可在基类基础上新增功能,不修改基类代码,符合开闭原则。
  1. 缺点
  • 增加类之间的耦合度,基类的修改可能影响所有派生类。
  • 菱形继承等场景容易引发二义性,需额外处理。
相关推荐
H_BB2 小时前
LRU缓存
数据结构·c++·算法·缓存
charlie1145141912 小时前
嵌入式现代C++:何时用 C++、用哪些 C++ 特性(折中与禁用项)
开发语言·c++·笔记·学习
山峰哥3 小时前
Python爬虫实战:从零构建高效数据采集系统
开发语言·数据库·爬虫·python·性能优化·架构
历程里程碑4 小时前
LeetCode热题11:盛水容器双指针妙解
c语言·数据结构·c++·经验分享·算法·leetcode·职场和发展
郝学胜-神的一滴4 小时前
使用OpenGL绘制卡通效果的圣诞树
开发语言·c++·程序人生·游戏·图形渲染
想回家的一天9 小时前
ECONNREFUSED ::1:8000 前端代理问题
开发语言
cike_y9 小时前
Mybatis之解析配置优化
java·开发语言·tomcat·mybatis·安全开发
Jay_Franklin10 小时前
SRIM通过python计算dap
开发语言·python
Slow菜鸟10 小时前
Java基础架构设计(三)| 通用响应与异常处理(分布式应用通用方案)
java·开发语言