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

c++总复习

1. 什么是继承性以及 C++ 中如何实现继承

(1)继承性的概念

继承(Inheritance)是面向对象编程中的一个重要特性,它允许创建新的类(称为派生类或子类)从已有的类(称为基类或父类)那里获取成员变量和成员函数。派生类继承了基类的特性,并且可以在此基础上进行扩展,添加新的成员或者重写基类中的某些函数,以满足特定的应用需求。形象地说,就好比子女继承父母的某些特征,并在此基础上发展出自己独特的个性一样。

例如,有一个基类Animal,它具有成员变量表示动物的年龄、体重等通用属性,以及成员函数如eat()表示吃东西这个行为。然后可以创建派生类Dog(狗类)从Animal类继承,Dog类除了拥有从Animal类继承来的这些基本特征外,还可以添加自己特有的成员,比如成员变量表示狗的品种,成员函数bark()表示狗叫的行为。

(2)C++ 中实现继承的语法

在 C++ 中,通过以下语法来实现继承:

class 派生类名 : 访问限定符 基类名 {
    // 派生类新添加的成员声明
};

其中,访问限定符可以是public(公有继承)、private(私有继承)或protected(保护继承),不同的访问限定符决定了基类成员在派生类中的访问权限以及通过派生类对象在外部对基类继承成员的访问情况,具体如下:

  • 公有继承(public
    • 基类的public成员在派生类中仍然是public成员,可以被派生类的对象以及外部代码通过派生类对象直接访问(前提是在合适的访问范围内)。
    • 基类的protected成员在派生类中依然是protected成员,可在派生类内部访问,但不能被外部代码通过派生类对象访问。
    • 基类的private成员在派生类中不可直接访问,只能通过基类提供的publicprotected的接口(如成员函数)来间接访问。
      例如:
class Animal {
public:
    int age;
    void eat() {
        std::cout << "Animal is eating." << std::endl;
    }
};

class Dog : public Animal {
public:
    void bark() {
        std::cout << "Dog is barking." << std::endl;
    }
};

在上述代码中,Dog类公有继承了Animal类,Dog类的对象可以直接访问从Animal类继承来的public成员变量age以及调用public成员函数eat(),同时Dog类自身又新增了成员函数bark()

  • 私有继承(private
    • 基类的publicprotected成员在派生类中都变为private成员,只能在派生类内部访问,外部代码不能通过派生类对象访问这些从基类继承来的成员。
      例如:
class Animal {
public:
    int age;
    void eat() {
        std::cout << "Animal is eating." << std::endl;
    }
};

class Cat : private Animal {
public:
    void meow() {
        // 在派生类内部可以访问从基类继承来的成员
        age = 5;
        eat();
        std::cout << "Cat is meowing." << stdendl;
    }
};

这里Cat类私有继承了Animal类,虽然在Cat类内部能访问Animal类的ageeat(),但外部代码不能通过Cat类对象去访问它们,比如下面这样的代码就是错误的:

Cat myCat;
myCat.age;  // 编译错误,因为在私有继承下,基类的public成员在派生类中变为private,外部不可访问
myCat.eat();  // 编译错误,同理
  • 保护继承(protected
    • 基类的publicprotected成员在派生类中都变为protected成员,它们能在派生类内部访问,也能在派生类的派生类(即孙子类等更深层次的派生类)中访问,但外部代码不能通过派生类对象访问这些成员。

例如:

class Animal {
public:
    int age;
    void eat() {
        std::cout << "Animal is eating." << std::endl;
    }
};

class Tiger : protected Animal {
public:
    void roar() {
        age = 10;
        eat();
        std::cout << "Tiger is roaring." << std::endl;
    }
};

Tiger类中可以访问从Animal类继承来的成员,不过外部代码不能直接通过Tiger类对象去访问它们,而且如果再有从Tiger类派生的类,依然可以访问这些变为protected的从Animal类继承来的成员(如果在合适的访问控制规则下)。

2. 继承的好处和注意事项

(1)继承的好处
  • 代码复用
    这是继承最显著的好处之一。通过继承基类,派生类无需重新编写基类中已有的代码,就能直接使用那些继承过来的成员变量和成员函数,大大减少了代码的重复编写,提高了开发效率。例如,在开发一个图形绘制系统时,如果已经有了一个表示基本图形的基类Shape,里面有计算面积、周长等通用的函数以及表示图形位置等基本属性的成员变量,后续创建如Circle(圆形)、Rectangle(矩形)等具体图形类时,通过继承Shape类,就不用再重新写那些通用的代码逻辑了,只需关注各自图形特有的属性和行为的实现即可。
  • 层次化建模
    便于对现实世界中的对象关系进行建模,构建出清晰的类层次结构。以动物世界为例,可以先创建一个抽象的Animal基类来表示所有动物共有的特征,然后派生出各种具体的动物类,如Mammal(哺乳动物类)、Bird(鸟类)等,这些类又可以进一步派生出更具体的动物子类,像DogCatMammal类派生,EagleSparrowBird类派生,这样的层次结构使得代码的组织和理解更加直观,符合人们对现实世界分类概念的认知。
  • 多态性的基础
    继承是实现多态(Polymorphism)的前提条件之一。多态允许不同派生类的对象对同一函数调用做出不同的响应,增强了程序的灵活性和可扩展性。比如,定义一个基类指针或引用,可以指向不同派生类的对象,当通过这个指针或引用调用虚函数(虚函数是实现多态的关键语法元素,常和继承结合使用)时,会根据对象的实际类型来决定调用哪个派生类中重写后的函数版本,这在很多需要灵活处理不同类型对象但又有统一接口调用的场景中非常有用,例如图形绘制系统中,统一通过基类指针调用绘制函数,不同图形类(派生类)各自实现绘制逻辑,就能方便地绘制出各种不同的图形。
(2)继承的注意事项
  • 继承层次不宜过深过复杂
    如果继承层次过多、过于复杂,代码的可读性和可维护性会大大降低。理解一个深层次继承关系下派生类的行为可能需要追溯多个基类的实现,容易造成混乱,也使得调试代码变得困难。例如,一个类经过七八层甚至更多层的派生,要弄清楚某个成员变量的最终来源以及其访问权限的变化情况等就会很麻烦,所以在设计类层次结构时,应尽量保持合理的继承深度,遵循简单清晰的原则。
  • 注意访问权限控制
    要谨慎选择继承时的访问限定符(publicprivateprotected),因为不同的限定符决定了基类成员在派生类以及外部的可访问性,错误的选择可能导致代码出现逻辑错误或者不符合预期的封装性。比如,如果希望派生类能向外暴露基类的某些公共接口,却错误地使用了私有继承,就会使得这些接口无法被外部正常访问,破坏了原本的设计意图。
  • 避免不合理的继承关系
    不是所有类之间都适合建立继承关系,要遵循 “is-a”(是一种)的语义原则来确定继承关系是否合理。例如,不能仅仅因为某个类和另一个类有一些共同的属性或方法就建立继承关系,如果不符合现实世界或逻辑上的分类概念,会让代码结构变得混乱且难以理解。比如,有一个Car(汽车)类和一个Wheel(车轮)类,虽然汽车包含车轮,但不能说汽车 “是一种” 车轮,所以它们之间不适合用继承关系来表示,而用组合(Car类可以有成员变量是Wheel类型的对象,表示汽车包含车轮这种组成关系)等其他方式来建模更合适。

http://www.kler.cn/a/428225.html

相关文章:

  • EasyExcel写入和读取多个sheet
  • 快速分析LabVIEW主要特征进行判断
  • 【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.20 极值追踪:高效获取数据特征的秘诀
  • MySQL通过binlog恢复数据
  • typescript 简介
  • 大一计算机的自学总结:位运算的应用及位图
  • 青牛科技---摄氏温度传感器D35使用手册
  • Linux Ubuntu
  • 聊聊用Rust来写CDD程序
  • mysql8 主从复制一直失败
  • leetcode 999. 可以被一步捕获的棋子数 简单
  • 【数字化】华为企业数字化转型-认知篇
  • centos安装jdk17 并自由切换jdk版本
  • 实用|金融银行项目测试业务流分析+常问面试题
  • 新能源汽车无钥匙进入一键启动功能介绍
  • 关于VS2019scanf的安全问题
  • Uniapp Android SpringBoot3 对接支付宝支付(最新教程附源码)
  • 【Linux】网络服务
  • k8s 之 DaemonSet
  • 【强化学习】策略梯度(Policy Gradient,PG)算法
  • 【MySQL】数据类型的注意点和应用
  • 008.精读《Apache Paimon Docs - Table w/o PK》
  • 【PyQt5教程 二】Qt Designer 信号与槽的使用方法及PyQt5基本小部件说明
  • CentOS8.5.2111(10)基于域名访问的邮件服务配置与管理
  • python录制鼠标键盘操作循环播放
  • LeetCode:28. 找出字符串中第一个匹配项的下标(KMP算法)