• 【C++进阶学习】第一弹——继承(上)——探索代码复用的乐趣


    前言:

    在前面,我们已经将C++的初阶部分全部讲完了,包括类与对象、STL、栈和队列等众多内容,今天我们就进入C++进阶部分的学习,今天先来学习第一弹——继承

    目录

    一、什么是继承?为什么会有继承?

    二、继承的基本概念

    2.1 继承的定义

    2.2 继承关系和访问限定符

    2.3 继承方式所带来的权限问题

    三、基类和派生类的赋值转换

    四、总结


    一、什么是继承?为什么会有继承?

    所谓继承,其实就是对代码复用的一种手段,通过一个已经存在的类来建立一个新类,并简化代码,比如当我们创建一个教师类和一个学生类的时候,他们所包含的信息分别是:学生:姓名、年龄、学号,老师:姓名、年龄、工号。

    对于这样两个类,他们所包含的信息有很高的重合度,如果我们写两个类来包含各自的信息,就会显得比较冗余,尤其当我们的代码量很大的时候,如何来复用代码,对于我们简化代码就很重要。下面我们通过上面所说的教师类和学生类来引出我们的继承!

    不用继承:

    1. #include
    2. #include
    3. using namespace std;
    4. class Teacher //教师类
    5. {
    6. public:
    7. void print()
    8. {
    9. cout << _name << endl;
    10. cout << _age << endl;
    11. }
    12. private:
    13. string _name = "zhangsan"; //名字
    14. int _age = 20; //年龄
    15. string _jobid; //工号
    16. };
    17. class student
    18. {
    19. public:
    20. void print()
    21. {
    22. cout << _name << endl;
    23. cout << _age << endl;
    24. }
    25. private:
    26. string _name = "zhangsan"; //名字
    27. int _age = 20; //年龄
    28. string _jobid; //学号
    29. };
    30. int main()
    31. {
    32. Teacher t;
    33. student s;
    34. t.print();
    35. s.print();
    36. return 0;
    37. }

    我们会发现这样的一段代码非常冗余,相同的成员变量和成员函数却要写两次,接下来我们就通过继承来简化这段代码

    继承:

    1. #include
    2. #include
    3. using namespace std;
    4. class Person
    5. {
    6. public:
    7. void Print()
    8. {
    9. cout << "name:" << _name << endl;
    10. cout << "age:" << _age << endl;
    11. }
    12. protected:
    13. string _name = "peter"; // 姓名
    14. int _age = 18; //年龄
    15. };
    16. class Student : public Person
    17. {
    18. protected:
    19. int _stuid; // 学号
    20. };
    21. class Teacher : public Person
    22. {
    23. protected:
    24. int _jobid; // 工号
    25. };
    26. int main()
    27. {
    28. Student s;
    29. Teacher t;
    30. s.Print();
    31. t.Print();
    32. return 0;
    33. }

    二、继承的基本概念

    2.1 继承的定义

    上面我们定义的Person类为父类,student和teacher类都是基类

    2.2 继承关系和访问限定符

    2.3 继承方式所带来的权限问题

    描述:

    上面所说的不可见其实就是不能直接访问的意思,通过上面的表格我们可以得到一个规律:派生类的权限大小取决于父类中成员的开放程度和继承方式,并且是以两者中权限小的为准

    三、基类和派生类的赋值转换

    基类和派生类有一个挺重要的问题就是互相之间的赋值转换,因为两者之间相似点还是很多的,所以他们两个之间是否可以相互转换呢?

    答案是:派生类可以赋值给基类,但是基类不能赋值给派生类

    派生类对象 可以赋值给 基类的对象 / 基类的指针 / 基类的引用 。这里有个形象的说法叫切片
    或者切割。寓意把派生类中父类那部分切来赋值过去。

    如图所示:

    下面我们给出赋值各种情况的代码,建议仔细阅读一下:

    1. #include
    2. #include
    3. using namespace std;
    4. class Person
    5. {
    6. protected:
    7. string _name; // 姓名
    8. string _sex; //性别
    9. int _age; // 年龄
    10. };
    11. class Student : public Person
    12. {
    13. public:
    14. int _No; // 学号
    15. };
    16. void Test()
    17. {
    18. Student sobj;
    19. // 1.子类对象可以赋值给父类对象/指针/引用
    20. Person pobj = sobj;
    21. Person* pp = &sobj;
    22. Person& rp = sobj;
    23. //2.基类对象不能赋值给派生类对象
    24. sobj = pobj;
    25. // 3.基类的指针可以通过强制类型转换赋值给派生类的指针
    26. pp = &sobj;
    27. Student * ps1 = (Student*)pp; // 这种情况转换时可以的。
    28. ps1->_No = 10;
    29. pp = &pobj;
    30. Student* ps2 = (Student*)pp; // 这种情况转换时虽然可以,但是会存在越界访问的问
    31. //题
    32. ps2->_No = 10; //这就是越界访问的情况
    33. }

    四、总结

    上面只是简单的讲了一下C++继承的一些知识,由于我们近期考试周的缘故,暂时就先写这么多了,下一篇我们将详细地介绍继承中一些更难的问题,比如多继承,菱形继承等问题,今天的文章就先到这了,感谢观看

    感谢各位大佬观看,创作不易,还请各位大佬点赞支持一下下呀!!!

  • 相关阅读:
    QT10_16
    TairSearch:加速多列索引查询
    springBoot--web--http缓存机制测试
    2023年中国石英矿资源现状及行业市场供需分析[图]
    Vue 3是一个错误,我们不应该再犯。
    组合计数3以及高斯消元
    力扣 -- 279. 完全平方数(完全背包问题)
    Spring Cloud OpenFeign
    python创建一个简单的flask应用
    D2-读论文D2&算法题D2(复习:单链表、双链表、模拟栈)
  • 原文地址:https://blog.csdn.net/2301_80220607/article/details/139689483