• C++:继承、继承对象模型、多继承、菱形继承 、虚继承的实现


    继承

    ●当定义一个新的类时,发现该类具备之前某一个类的基本属性及方法时,就可使用继承技术.

    ●意义:减少代码重复率,增加代码利用率

    一、继承对象模型

    (1)C++对象中,成员属性与成员函数是分开存储的,对象的内存大小和成员函数没有关系,但是成员函数在逻辑上是属于类的.

    (2)继承关系中,子类会继承所有父类的==成员属性以及成员函数.==但是私有属性被继承后被编译器屏蔽,所以私有成员是不能访问的.

    (3)继承关系中,先构造父对象、再构造子对象,析构顺序相反.

    (4)如果出现子类成员与父类成员同名情况,则父类的成员会被隐藏,对象直接访问的话,访问到的是子类自己的成员。则需要使用作用域符号::

    (5)●在继承模型中,父类中的静态成员变量以及静态成员函数,也会被子类的所有对象共享。(static)--à菱形继承

    访问子类:

    obj . age

    访问父类:

    obj. Base: :age  

    代码1):成员属性与成员函数是分开存储

    1. #include
    2. using namespace std;
    3. class Data
    4. {
    5. int _data1;
    6. int _data3;
    7. static int _data2; //不占空间
    8. //不占空间
    9. void fun()
    10. {
    11. cout<<"fun"<
    12. }
    13. };
    14. int Data::_data2=0;
    15. int main(int argc, char *argv[])
    16. {
    17. cout<<"sizeof(Data):"<<sizeof(Data)<
    18. return 0;
    19. }

    代码2):继承关系

    1. #include
    2. using namespace std;
    3. class Data
    4. {
    5. private:
    6. int _data1;
    7. protected:
    8. int _data3;
    9. public:
    10. int _data4;
    11. static int _data2;
    12. void fun1()
    13. {
    14. cout << "fun1" << endl;
    15. }
    16. void fun2()
    17. {
    18. cout << "fun2" << endl;
    19. }
    20. };
    21. int Data::_data2 = 0;
    22. class SonData:protected Data
    23. {
    24. public:
    25. void Visit()
    26. {
    27. cout << _data4 << endl;
    28. cout << _data3 << endl;
    29. //cout << _data1 << endl;
    30. cout << _SonData << endl;
    31. }
    32. private:
    33. int _SonData;
    34. };
    35. int main()
    36. {
    37. cout << "sizeof(Data): " << sizeof(Data) << endl;
    38. cout << "sizeof(SonData): " << sizeof(SonData) << endl;
    39. SonData s1;
    40. s1.Visit();
    41. //s1._data4;
    42. return 0;
    43. }

    二、多继承

    (1)当一个类继承多个类时,被称为多继承关系.

    class A: <继承权限> <类名>, <继承权限> <类名>

    {

    }

    ●注意:实际开发应该减少多继承方式  

    代码3):多继承

    1. #include
    2. using namespace std;
    3. class Sheep
    4. {
    5. public:
    6. Sheep():s_kind("羊")
    7. {
    8. age=12;
    9. }
    10. int age;
    11. string s_kind;
    12. };
    13. class Cow
    14. {
    15. public:
    16. Cow():c_kind("牛")
    17. {
    18. age=3;
    19. }
    20. int age;
    21. string c_kind;
    22. };
    23. class SiBuXiang:public Sheep,public Cow
    24. {
    25. public:
    26. int age;
    27. };
    28. void test01()
    29. {
    30. SiBuXiang s1;
    31. cout<
    32. //cout<
    33. cout<
    34. }
    35. int main(int argc, char *argv[])
    36. {
    37. test01();
    38. return 0;
    39. }

    三、虚继承

    (1)在多继承基础上,如果多个父类又是继承于同一个父类,那么成员访问就会出现问题,这种继承方式又称菱形继承  

    代码4):菱形继承  

    1. #include
    2. using namespace std;
    3. class A
    4. {
    5. public:
    6. static int dataA;
    7. };
    8. int A::dataA=1;
    9. class B:public A
    10. {
    11. };
    12. int main(int argc, char *argv[])
    13. {
    14. B b1;
    15. B b2;
    16. b1.dataA=6;
    17. cout<
    18. cout<
    19. cout<<&(B::dataA)<
    20. A a1;
    21. a1.dataA=78;
    22. cout<<&(a1.dataA)<
    23. cout<<&(A::dataA)<
    24. cout<
    25. cout<
    26. return 0;
    27. }

    (2)虚继承方式:

    class B:virtual public A

    {
    }

    (3)作用:虚继承不是真正的继承成员属性,而是生成一个虚基类指针(vbptr),该指针可以实现访问同一个属性,而不出现二义性.

    (4)原理:虚基类指针vbptr指向一个虚基类表,表中记录了到虚基类中成员变量的偏移量,通过偏移量就能够量就能够正确找到同一个成员变量.  

    代码4):虚继承

    1. #include
    2. using namespace std;
    3. class Animal
    4. {
    5. public:
    6. Animal():age(23)
    7. {
    8. }
    9. int age;
    10. static int n;
    11. };
    12. int Animal::n=10;
    13. class Sheep:virtual public Animal //virtual
    14. {
    15. public:
    16. int SNum;
    17. };
    18. class Cow:virtual public Animal //virtual
    19. {
    20. public:
    21. int CNum;
    22. };
    23. class SiBuXiang:public Cow,public Sheep
    24. {
    25. public:
    26. };
    27. void test01()
    28. {
    29. SiBuXiang s1;
    30. cout<
    31. cout<//static 共享
    32. }
    33. void test02()
    34. {
    35. SiBuXiang s2;
    36. s2.age=9;
    37. cout<
    38. cout<
    39. }
    40. int main(int argc, char *argv[])
    41. {
    42. test01();
    43. test02();
    44. return 0;
    45. }

  • 相关阅读:
    【Java】内部类、File类、线程优先级
    Nginx+Tomcat负载均衡、动静分离
    【javascript】按下回车键登陆实现
    知网CN《知识文库》期刊简介及投稿邮箱
    【【萌新的RISC-V学习之再看计算机组成与设计大收获总六】】
    纵横网络靶场 部分wp
    C14—使用QT制作玫瑰散落特效定制程序员的专属浪漫-2022-11-14
    基于Matlab仿真无源雷达传感器和雷达干扰(附源码)
    Java--多线程
    2021年山东省职业院校技能大赛中职组”网络安全“正式赛题
  • 原文地址:https://blog.csdn.net/qq_63626307/article/details/126754365