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. 缺点
  • 增加类之间的耦合度,基类的修改可能影响所有派生类。
  • 菱形继承等场景容易引发二义性,需额外处理。
相关推荐
九转成圣2 小时前
Java 性能优化实战:如何将海量扁平数据高效转化为类目字典树?
java·开发语言·json
SmartRadio2 小时前
ESP32-S3 双模式切换实现:兼顾手机_路由器连接与WiFi长距离通信
开发语言·网络·智能手机·esp32·长距离wifi
laowangpython3 小时前
Rust 入门:GitHub 热门内存安全编程语言
开发语言·其他·rust·github
我叫汪枫3 小时前
在后台管理系统中,如何递归和选择保留的思路来过滤菜单
开发语言·javascript·node.js·ecmascript
_.Switch3 小时前
东方财富股票数据JS逆向:secids字段和AES加密实战
开发语言·前端·javascript·网络·爬虫·python·ecmascript
软件技术NINI3 小时前
webkit简介及工作流程
开发语言·前端·javascript·udp·ecmascript·webkit·yarn
Brendan_0013 小时前
JavaScript的Stomp.over
开发语言·javascript·ecmascript
念2343 小时前
f5 shape分析
开发语言·javascript·ecmascript
苍穹之跃3 小时前
某量JS逆向
开发语言·javascript·ecmascript
思茂信息3 小时前
CST软件如何进行参数化扫描?
运维·开发语言·javascript·windows·ecmascript·软件工程·软件需求