zoukankan      html  css  js  c++  java
  • C++语言类之间的关系

    在c++中通过类定义对象,而类与类之间也有着复杂的关系,所以题外话,我能理解到c++的编写者可能就想通过计算机语言去模拟世界万物之间的关系,这篇帖子主要从横向和纵向去讨论类之间关系

    而在一个类中想要使用另一个类中的内容,无非三种方式,1.直接传参 2.传地址 3.在一个类中去定义另一个类

    从横向来看,可以分为1.依赖 2.关联 3.聚合 4.复合,接下来用UML类图展示一下这几种横向关系

     第一种,依赖,一个对象的一个功能需要依赖另一个对象存在,被依赖的对象作为工具使用,   在上图的例子中,CComputer 这个类对于CPerson来说,是作为Coding的一个工具,CComputer不是CPerson的一个特性,所以是依赖关系

    第二种,关联,就类似于朋友之间的平等关系,关联的特点是随时建立,随时解除,利用指针去指向CFriend的地址

    第三种,聚合,相当于强版本的关联,但聚合的目的是为了统一进行管理同类型的对象,就像是一个家庭,或者是一个班级,所以一般这里的对象都需要new出来的, 在聚合的析构里可以统一删除,统一创建

    第四种,复合,又叫组合,是属于CPerson的一部分,类似于脑袋,双手

    之所以建立这种类之间的关系,也是根据c++的单一性这个特点,每一个部分都是一个独立的个体,一个类的修改不会影响到其他的部分,也可以进行任意组合,下面是针对这个类图的代码

      1 #include <iostream>
      2 #include <time.h>
      3 using namespace std;
      4 
      5 
      6 class CHead
      7 {
      8 public:
      9     void Say()
     10     {
     11         cout << "张个大嘴,哇啦哇啦" << endl;
     12     }
     13 };
     14 
     15 class CHand
     16 {
     17 public:
     18     void Move()
     19     {
     20         cout << "比比划划" << endl;
     21     }
     22 };
     23 
     24 class CComputer
     25 {
     26 public:
     27     void Coding()
     28     {
     29         cout << "C++ Coding....." << endl;
     30     }
     31 };
     32 
     33 class CFriend
     34 {
     35 public:
     36     int rp;
     37 public:
     38     CFriend()
     39     {
     40         rp = rand()%10;
     41     }
     42 public:
     43     void Play()
     44     {
     45         cout << "哈哈哈哈哈哈" << endl;
     46     }
     47 };
     48 
     49 
     50 
     51 class CPerson
     52 {
     53 public:
     54     CHead head;    //  组合
     55     CHand hand;
     56     CFriend* m_pFriend;   //  关联一个朋友
     57 public:
     58     CPerson()
     59     {
     60         m_pFriend = 0;
     61     }
     62 public:
     63     void FindFriend(CFriend* pFriend)
     64     {
     65         if(pFriend == 0)
     66             return;
     67 
     68         if(pFriend->rp > 4)
     69         {
     70             m_pFriend = pFriend;
     71         }
     72     }
     73     void ChickenDinner()
     74     {
     75         if(m_pFriend == 0)
     76         {
     77             cout << "~~~~(>_<)~~~~玩的不开心" << endl;
     78         }
     79         else
     80         {
     81             m_pFriend->Play();
     82         }
     83     }
     84     void Say()
     85     {
     86         head.Say();
     87         hand.Move();
     88     }
     89     void Coding(CComputer& cm)   //  依赖一个电脑
     90     {
     91         head.Say();
     92         cm.Coding();
     93     }
     94 };
     95 
     96 
     97 
     98 class CFamily
     99 {
    100 public:
    101     CPerson* pArr[5];    //  聚合到 家庭中
    102 public:
    103     CFamily()
    104     {
    105         for(int i=0;i<5;i++)
    106             pArr[i] = 0;
    107     }
    108     ~CFamily()
    109     {
    110         for(int i=0;i<5;i++)
    111         {
    112             if(pArr[i] != 0)
    113             {
    114                 delete pArr[i];
    115                 pArr[i] = 0;
    116             }
    117         }
    118     }
    119 public:
    120     void PushPerson(CPerson* ps)
    121     {
    122         if(ps == 0)
    123             return;
    124         for(int i=0;i<5;i++)
    125         {
    126             if(pArr[i] == 0)
    127             {
    128                 pArr[i] = ps;
    129                 return;
    130             }
    131         }
    132     }
    133     void AllPersonCoding(CComputer& cm)
    134     {
    135         for(int i=0;i<5;i++)
    136         {
    137             if(pArr[i] != 0)
    138             {
    139                 pArr[i]->Coding(cm);
    140             }
    141         }        
    142     }
    143 };
    144 
    145 
    146 
    147 
    148 int main()
    149 {
    150 
    151     //srand((unsigned int)time(0));
    152 
    153     //CComputer cm;
    154     //CFriend ff;
    155 
    156     //CPerson ps;
    157     //ps.Say();
    158     //ps.Coding(cm);
    159 
    160     //ps.FindFriend(&ff);
    161     //ps.ChickenDinner();
    162 
    163     //--------------------------------------------------
    164     CPerson* ps1 = new CPerson;
    165     CPerson* ps2 = new CPerson;
    166     CPerson* ps3 = new CPerson;
    167 
    168     CComputer cm;
    169     CFamily fm;
    170     fm.PushPerson(ps1);
    171     fm.PushPerson(ps2);
    172     fm.PushPerson(ps3);
    173     fm.AllPersonCoding(cm);
    174 
    175     system("pause");
    176     return 0;
    177 }

    而从纵向关系来看的关系有1.继承 2.多态

    首先来说继承,继承中分为基类(父类),派生类(子类),继承的优点就是,提高代码的复用性,在派生类中,基类的所有成员都可以使用,而具体能否使用就得看继承的方式了

    a.public继承,子类,public不变,protected不变,private变成不可访问的

    b.protected 继承,子类,public->protected, protected不变, private变成不可访问的

    c.private继承,子类,public->private, protected->private,private变成不可访问的

    而需要注意的两点是

    1. 继承的方式影响的是派生类的派生类
    2. 继承的方式影响的只是基类的成员,不影响本类的访问修饰符

    继承中还有一点就是继承关系的构造析构

    1. 继承里子类构造的初始化列表里默认为父类的初始化(很重要的一点)
    2. 局部顺序

    子类构造->子类初始化列表->完成父类构造->完成子类构造->完成子类析构->回收子类空间->完成父类析构(在虚析构当中,虚函数完成的只是通过父类析构找到子类析构的过程,之后的过程和这个是一样的)

    做一个小实验可以很好的看出来顺序

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class CPerson
     5 {
     6 public:
     7     CPerson()
     8     {
     9         cout << "CPerson()" << endl;
    10     }
    11     ~CPerson()
    12     {
    13         cout << "~CPerson()" << endl;
    14     }
    15 };
    16 class CSon : public CPerson
    17 {
    18 public:
    19     CSon()
    20     {
    21         cout << "CSon" << endl;
    22     }
    23     ~CSon()
    24     {
    25         cout << "~CSon" << endl;
    26     }
    27 };
    28 int main()
    29 {
    30     {
    31         CSon cs;
    32     }
    33 
    34 
    35 
    36     system("pause");
    37     return 0;
    38 }

    第二个,多态,可以看一下上一篇帖子里 对于多态的讨论

    2019-05-30 11:31:45 编程小菜鸟自我反思,大家可以留下自己的建议和意见,谢谢!!!

  • 相关阅读:
    [转] ORACLE 错误编号表一
    基于CkEditor实现.net在线开发之路(1)
    跨行清算系统的实现原理
    应用程序域
    支付机构客户备付金存管办法
    数据库培训二期试题
    MYSQL开发规范
    详解线上线下收单业务(一)第三方支付
    Solr安装配置说明
    进程(Process)
  • 原文地址:https://www.cnblogs.com/xgmzhna/p/10948636.html
Copyright © 2011-2022 走看看