• C++学习寄录(八.继承)


    继承的语法:`class 子类 : 继承方式 父类`

    class A : public B;

    A 类称为子类 或 派生类

    B 类称为父类 或 基类

    1.基本使用

    未使用继承的代码比较冗余重复

    1. #include <iostream>
    2. #include <fstream>
    3. #include <string>
    4. #include <chrono>
    5. #include <ctime>
    6. #include <thread>
    7. using namespace std;
    8. //Java页面
    9. class Java
    10. {
    11. public:
    12. void header()
    13. {
    14. std::cout << "首页、公开课、登录、注册...(公共头部)" << std::endl;
    15. }
    16. void footer()
    17. {
    18. cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
    19. }
    20. void left()
    21. {
    22. cout << "Java,Python,C++...(公共分类列表)" << endl;
    23. }
    24. void content()
    25. {
    26. cout << "JAVA学科视频" << endl;
    27. }
    28. };
    29. //Python页面
    30. class Python
    31. {
    32. public:
    33. void header()
    34. {
    35. cout << "首页、公开课、登录、注册...(公共头部)" << endl;
    36. }
    37. void footer()
    38. {
    39. cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
    40. }
    41. void left()
    42. {
    43. cout << "Java,Python,C++...(公共分类列表)" << endl;
    44. }
    45. void content()
    46. {
    47. cout << "Python学科视频" << endl;
    48. }
    49. };
    50. //C++页面
    51. class CPP
    52. {
    53. public:
    54. void header()
    55. {
    56. cout << "首页、公开课、登录、注册...(公共头部)" << endl;
    57. }
    58. void footer()
    59. {
    60. cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
    61. }
    62. void left()
    63. {
    64. cout << "Java,Python,C++...(公共分类列表)" << endl;
    65. }
    66. void content()
    67. {
    68. cout << "C++学科视频" << endl;
    69. }
    70. };
    71. void test01()
    72. {
    73. //Java页面
    74. cout << "Java下载视频页面如下: " << endl;
    75. Java ja;
    76. ja.header();
    77. ja.footer();
    78. ja.left();
    79. ja.content();
    80. cout << "--------------------" << endl;
    81. //Python页面
    82. cout << "Python下载视频页面如下: " << endl;
    83. Python py;
    84. py.header();
    85. py.footer();
    86. py.left();
    87. py.content();
    88. cout << "--------------------" << endl;
    89. //C++页面
    90. cout << "C++下载视频页面如下: " << endl;
    91. CPP cp;
    92. cp.header();
    93. cp.footer();
    94. cp.left();
    95. cp.content();
    96. }
    97. int main() {
    98. test01();
    99. return 0;
    100. }

    使用继承后

    1. #include <iostream>
    2. #include <fstream>
    3. #include <string>
    4. #include <chrono>
    5. #include <ctime>
    6. #include <thread>
    7. using namespace std;
    8. //公共页面
    9. class BasePage
    10. {
    11. public:
    12. void header()
    13. {
    14. cout << "首页、公开课、登录、注册...(公共头部)" << endl;
    15. }
    16. void footer()
    17. {
    18. cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
    19. }
    20. void left()
    21. {
    22. cout << "Java,Python,C++...(公共分类列表)" << endl;
    23. }
    24. };
    25. //Java页面
    26. class Java : public BasePage
    27. {
    28. public:
    29. void content()
    30. {
    31. cout << "JAVA学科视频" << endl;
    32. }
    33. };
    34. //Python页面
    35. class Python : public BasePage
    36. {
    37. public:
    38. void content()
    39. {
    40. cout << "Python学科视频" << endl;
    41. }
    42. };
    43. //C++页面
    44. class CPP : public BasePage
    45. {
    46. public:
    47. void content()
    48. {
    49. cout << "C++学科视频" << endl;
    50. }
    51. };
    52. void test01()
    53. {
    54. //Java页面
    55. cout << "Java下载视频页面如下: " << endl;
    56. Java ja;
    57. ja.header();
    58. ja.footer();
    59. ja.left();
    60. ja.content();
    61. cout << "--------------------" << endl;
    62. //Python页面
    63. cout << "Python下载视频页面如下: " << endl;
    64. Python py;
    65. py.header();
    66. py.footer();
    67. py.left();
    68. py.content();
    69. cout << "--------------------" << endl;
    70. //C++页面
    71. cout << "C++下载视频页面如下: " << endl;
    72. CPP cp;
    73. cp.header();
    74. cp.footer();
    75. cp.left();
    76. cp.content();
    77. }
    78. int main() {
    79. test01();
    80. return 0;
    81. }

    继承方式

     2.继承中构造和析构顺序

    子类继承父类后,当创建子类对象,也会调用父类的构造函数

    问题:父类和子类的构造和析构顺序是谁先谁后?

    答:继承中 先调用父类构造函数,再调用子类构造函数,析构顺序与构造相反

    代码如下

    1. #include <iostream>
    2. #include <fstream>
    3. #include <string>
    4. #include <chrono>
    5. #include <ctime>
    6. #include <thread>
    7. using namespace std;
    8. class Base
    9. {
    10. public:
    11. Base()
    12. {
    13. cout << "Base构造函数!" << endl;
    14. }
    15. ~Base()
    16. {
    17. cout << "Base析构函数!" << endl;
    18. }
    19. };
    20. class Son : public Base
    21. {
    22. public:
    23. Son()
    24. {
    25. cout << "Son构造函数!" << endl;
    26. }
    27. ~Son()
    28. {
    29. cout << "Son析构函数!" << endl;
    30. }
    31. };
    32. int main() {
    33. //继承中 先调用父类构造函数,再调用子类构造函数,析构顺序与构造相反
    34. Son s;
    35. return 0;
    36. }

    输出为:

    Base构造函数!
    Son构造函数!
    Son析构函数!
    Base析构函数!

    3.继承同名成员处理方式

    当子类与父类出现同名的成员,如何通过子类对象,访问到子类或父类中同名的数据呢?

    * 访问子类同名成员 直接访问即可

    * 访问父类同名成员 需要加作用域

    代码如下

    1. #include <iostream>
    2. #include <fstream>
    3. #include <string>
    4. #include <chrono>
    5. #include <ctime>
    6. #include <thread>
    7. using namespace std;
    8. class Base {
    9. public:
    10. Base()
    11. {
    12. m_A = 100;
    13. }
    14. void func()
    15. {
    16. cout << "Base - func()调用" << endl;
    17. }
    18. void func(int a)
    19. {
    20. cout << "Base - func(int a)调用" << endl;
    21. }
    22. public:
    23. int m_A;
    24. };
    25. class Son : public Base {
    26. public:
    27. Son()
    28. {
    29. m_A = 200;
    30. }
    31. //当子类与父类拥有同名的成员函数,子类会隐藏父类中所有版本的同名成员函数
    32. //如果想访问父类中被隐藏的同名成员函数,需要加父类的作用域
    33. void func()
    34. {
    35. cout << "Son - func()调用" << endl;
    36. }
    37. public:
    38. int m_A;
    39. };
    40. int main() {
    41. Son s;
    42. cout << "Son下的m_A = " << s.m_A << endl;
    43. cout << "Base下的m_A = " << s.Base::m_A << endl;
    44. s.func();
    45. s.Base::func();
    46. s.Base::func(10);
    47. return 0;
    48. }

    输出为

    Son下的m_A = 200
    Base下的m_A = 100
    Son - func()调用
    Base - func()调用
    Base - func(int a)调用

    总结:

    1. 子类对象可以直接访问到子类中同名成员

    2. 子类对象加作用域可以访问到父类同名成员

    3. 当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数

    4.继承同名静态成员处理方式

    问题:继承中同名的静态成员在子类对象上如何进行访问?

    静态成员和非静态成员出现同名,处理方式一致

    - 访问子类同名成员 直接访问即可

    - 访问父类同名成员 需要加作用域

    代码

    1. #include <iostream>
    2. #include <fstream>
    3. #include <string>
    4. #include <chrono>
    5. #include <ctime>
    6. #include <thread>
    7. using namespace std;
    8. class Base {
    9. public:
    10. static void func()
    11. {
    12. cout << "Base - static void func()" << endl;
    13. }
    14. static void func(int a)
    15. {
    16. cout << "Base - static void func(int a)" << endl;
    17. }
    18. static int m_A;
    19. };
    20. int Base::m_A = 100;
    21. class Son : public Base {
    22. public:
    23. static void func()
    24. {
    25. cout << "Son - static void func()" << endl;
    26. }
    27. static int m_A;
    28. };
    29. int Son::m_A = 200;
    30. //同名成员属性
    31. void test01()
    32. {
    33. //通过对象访问
    34. cout << "通过对象访问: " << endl;
    35. Son s;
    36. cout << "Son 下 m_A = " << s.m_A << endl;
    37. cout << "Base 下 m_A = " << s.Base::m_A << endl;
    38. //通过类名访问
    39. cout << "通过类名访问: " << endl;
    40. cout << "Son 下 m_A = " << Son::m_A << endl;
    41. cout << "Base 下 m_A = " << Son::Base::m_A << endl;
    42. }
    43. //同名成员函数
    44. void test02()
    45. {
    46. //通过对象访问
    47. cout << "通过对象访问: " << endl;
    48. Son s;
    49. s.func();
    50. s.Base::func();
    51. cout << "通过类名访问: " << endl;
    52. Son::func();
    53. Son::Base::func();
    54. //出现同名,子类会隐藏掉父类中所有同名成员函数,需要加作作用域访问
    55. Son::Base::func(100);
    56. }
    57. int main() {
    58. test01();
    59. // test02();
    60. system("pause");
    61. return 0;
    62. }

    输出为:

    通过对象访问: 
    Son  下 m_A = 200
    Base 下 m_A = 100
    通过类名访问: 
    Son  下 m_A = 200
    Base 下 m_A = 100
    sh: 1: pause: not found

    总结:同名静态成员处理方式和非静态处理方式一样,只不过有两种访问的方式(通过对象 和 通过类名)

    5.多继承语法

    语法:` class 子类 :继承方式 父类1 , 继承方式 父类2...`

    多继承可能会引发父类中有同名成员出现,需要加作用域区分

    1. #include <iostream>
    2. #include <fstream>
    3. #include <string>
    4. #include <chrono>
    5. #include <ctime>
    6. #include <thread>
    7. using namespace std;
    8. class Base1 {
    9. public:
    10. Base1()
    11. {
    12. m_A = 100;
    13. }
    14. public:
    15. int m_A;
    16. };
    17. class Base2 {
    18. public:
    19. Base2()
    20. {
    21. m_A = 200; //开始是m_B 不会出问题,但是改为mA就会出现不明确
    22. }
    23. public:
    24. int m_A;
    25. };
    26. //语法:class 子类:继承方式 父类1 ,继承方式 父类2
    27. class Son : public Base2, public Base1
    28. {
    29. public:
    30. Son()
    31. {
    32. m_C = 300;
    33. m_D = 400;
    34. }
    35. public:
    36. int m_C;
    37. int m_D;
    38. };
    39. //多继承容易产生成员同名的情况
    40. //通过使用类名作用域可以区分调用哪一个基类的成员
    41. void test01()
    42. {
    43. Son s;
    44. cout << "sizeof Son = " << sizeof(s) << endl;
    45. cout << s.Base1::m_A << endl;
    46. cout << s.Base2::m_A << endl;
    47. }
    48. int main() {
    49. test01();
    50. return 0;
    51. }

    输出为:

    sizeof Son = 16
    100
    200

    总结: 多继承中如果父类中出现了同名情况,子类使用时候要加作用域

  • 相关阅读:
    机器人制作开源方案 | 家庭清扫拾物机器人
    题解_notion(持续更新ing)
    记mapboxGL实现鼠标经过高亮时的一个问题
    一个基于RedisTemplate静态工具类
    element plus封装el-select添加后缀图标并添加远程搜索和对话框功能
    V2X应用 汇总
    【路径规划-PRM路径规划】基于RRT算法避障路径规划附完整matlab代码
    Web3.0简介
    GAN Step By Step -- Step2 GAN的详细介绍及其应用
    MySQL八股文背诵版
  • 原文地址:https://blog.csdn.net/qq_46454669/article/details/134699485