当前位置: 首页 > news >正文

深入浅出C++继承机制:从入门到实战

目录

深入浅出C++继承机制:从入门到实战

一、继承的基本概念

二、继承的访问控制

三、继承中的特殊关系

1. 基类与派生类的转换

2. 继承中的作用域

3. 派生类的默认成员函数

四、多继承与菱形继承

1. 多继承模型

2. 菱形继承问题

3. 虚继承解决方案

五、继承与组合的选择

六、继承实战技巧

七、总结


深入浅出C++继承机制:从入门到实战

面向对象编程中,继承是最强大的特性之一,也是C++程序员必须掌握的核心概念。今天我们就来全面解析C++继承机制,从基础概念到高级应用,让你彻底搞懂继承!

一、继承的基本概念

继承是面向对象程序设计使代码可以复用的最重要手段。想象一下,学校里有老师和学生,他们都有姓名、年龄、地址等共同属性,但又有各自独特的属性(老师有职称,学生有学号)。如果分别定义两个类,就会出现大量重复代码。

class Person {
protected:string _name = "张三"; // 姓名int _age = 18;        // 年龄string _address;      // 地址string _tel;          // 电话
};class Student : public Person {
protected:int _stuid; // 学号
};class Teacher : public Person {
protected:string _title; // 职称
};

通过继承,我们可以把公共成员放到Person基类中,Student和Teacher都继承Person,这样就避免了重复定义,代码更加简洁优雅。

二、继承的访问控制

继承方式有三种:public、protected和private。它们决定了基类成员在派生类中的访问权限:

基类成员/继承方式public继承protected继承private继承
public成员publicprotectedprivate
protected成员protectedprotectedprivate
private成员不可见不可见不可见

几点重要说明:

  1. 基类private成员在派生类中无论以什么方式继承都是不可见的
  2. protected成员是专为继承设计的访问级别
  3. 实际开发中绝大多数情况使用public继承
class Base {
public:int publicVar;
protected:int protectedVar;
private:int privateVar;
};class Derived : public Base {// publicVar仍然是public// protectedVar仍然是protected// privateVar不可见
};

三、继承中的特殊关系

1. 基类与派生类的转换

Student sobj;
// 派生类对象可以赋值给基类的指针/引用(切片)
Person* pp = &sobj;
Person& rp = sobj;// 基类对象不能赋值给派生类对象(编译报错)
// sobj = pobj; 

2. 继承中的作用域

当基类和派生类有同名成员时,派生类成员会隐藏基类成员:

class Base {
public:void func() { cout << "Base::func()" << endl; }
};class Derived : public Base {
public:void func() { cout << "Derived::func()" << endl; }// 如果要访问基类的func,需要使用Base::func()
};

3. 派生类的默认成员函数

派生类的构造/析构等特殊成员函数有一些特殊规则:

class Person {
public:Person(const char* name = "peter") : _name(name) {}// ...
};class Student : public Person {
public:Student(const char* name, int num): Person(name)  // 必须调用基类构造函数, _num(num) {}// ...
};

四、多继承与菱形继承

1. 多继承模型

class Worker {// 工人特有属性和方法
};class Student {// 学生特有属性和方法
};class WorkingStudent : public Worker, public Student {// 既是工人又是学生
};

2. 菱形继承问题

菱形继承是多继承的一种特殊情况,会导致数据冗余和二义性:

class Person {string _name;
};class Student : public Person {int _num;
};class Teacher : public Person {int _id;
};class Assistant : public Student, public Teacher {// 这里Person的成员会有两份!
};

3. 虚继承解决方案

使用虚继承可以解决菱形继承问题:

class Person {string _name;
};class Student : virtual public Person {int _num;
};class Teacher : virtual public Person {int _id;
};class Assistant : public Student, public Teacher {// 现在_name只有一份了
};

五、继承与组合的选择

在设计类关系时,需要慎重考虑使用继承还是组合:

// 继承(is-a关系)
class BMW : public Car {void Drive() { cout << "好开-操控" << endl; }
};// 组合(has-a关系)
class Stack {vector<int> _v;  // 使用组合而非继承
};

一般原则:

  • 如果确实是"is-a"关系,使用继承
  • 如果是"has-a"关系,使用组合
  • 当两者都适用时,优先考虑组合

六、继承实战技巧

  1. ​final关键字​​:C++11引入final关键字,可以禁止类被继承
class Base final {// 这个类不能被继承
};
  1. ​静态成员继承​​:基类的静态成员在整个继承体系中只有一份
class Base {
public:static int count;
};
int Base::count = 0;class Derived : public Base {// 共享同一个count
};
  1. ​友元关系不继承​​:基类的友元不能访问派生类的私有成员

七、总结

继承是C++面向对象编程的核心特性,合理使用可以:

  • 提高代码复用性
  • 建立清晰的类层次结构
  • 实现多态(配合虚函数)

但也要注意:

  • 避免过度使用继承
  • 警惕菱形继承问题
  • 在继承和组合之间做出明智选择

掌握好继承机制,你的C++面向对象设计能力将更上一层楼!


文章转载自:

http://RSXrl6fZ.xmhpq.cn
http://xWGmNyjB.xmhpq.cn
http://ovJ4SoR3.xmhpq.cn
http://vsE2DTzd.xmhpq.cn
http://kFDDEuBJ.xmhpq.cn
http://oyaY2juV.xmhpq.cn
http://57580HLA.xmhpq.cn
http://ZBHD32BA.xmhpq.cn
http://MgE9I7hh.xmhpq.cn
http://KhhNY7dC.xmhpq.cn
http://BNn2ugfb.xmhpq.cn
http://wBNBgqLO.xmhpq.cn
http://7E5jRDVo.xmhpq.cn
http://qNW8jaGU.xmhpq.cn
http://DkgGJoJs.xmhpq.cn
http://KNhGCiPh.xmhpq.cn
http://7ou6curC.xmhpq.cn
http://svjPtBCe.xmhpq.cn
http://WQdSnukZ.xmhpq.cn
http://M2KdD7A6.xmhpq.cn
http://LPoJMEB8.xmhpq.cn
http://20WOH9AZ.xmhpq.cn
http://kPM9k7GH.xmhpq.cn
http://AflvuqpL.xmhpq.cn
http://VUntbQf4.xmhpq.cn
http://jtWmgCn4.xmhpq.cn
http://WPh3IOft.xmhpq.cn
http://DYFoRNhT.xmhpq.cn
http://fKibiSWV.xmhpq.cn
http://fkSpWF5I.xmhpq.cn
http://www.dtcms.com/a/375354.html

相关文章:

  • 级联框的实现
  • android 性能优化—内存泄漏,内存溢出OOM
  • 从PyTorch到ONNX:模型部署性能提升
  • JAVA:实现快速排序算法的技术指南
  • SQL 触发器从入门到进阶:原理、时机、实战与避坑指南
  • 无标记点动捕技术:重塑展厅展馆的沉浸式数字交互新时代
  • 【Agent】DeerFlow Planner:执行流程与架构设计(基于真实 Trace 深度解析)
  • R语言读取excel文件数据-解决na问题
  • 在钉钉上长出的AI组织:森马的路径与启示
  • IntelliJ IDEA 中 JVM 配置参考
  • JVM(二)--- 类加载子系统
  • 9.ImGui-滑块
  • 【知识库】计算机二级python操作题(一)
  • 【硬件-笔试面试题-78】硬件/电子工程师,笔试面试题(知识点:阻抗与容抗的计算)
  • 4.5Vue的列表渲染
  • 使用YOLO11进行路面裂缝检测
  • 常见并行概念解析
  • 9月9日
  • centos系统上部署安装minio
  • 下载CentOS 7——从阿里云上下载不同版本的 CentOS 7
  • 《预约一团乱麻?预约任务看板让你告别排班噩梦!宠物店效率翻倍指南》
  • Shell 脚本条件测试与 if 语句
  • 【倒数日子隐私收集】
  • Diamond基础4:仿真流程、添加原语IP核
  • Java入门级教程14——同步安全机制明锁
  • [JavaWeb]模拟一个简易的Tomcat服务(Servlet注解)
  • MongoDB vs MySQLNoSQL与SQL数据库的架构差异与选型指南
  • Vue框架技术详解——项目驱动概念理解【前端】【Vue】
  • mardown-it 有序列表ios序号溢出解决办法
  • 目前主流热门的agent框架