美文网首页
C++类的复合和继承关系(C++继承类和封闭类的关系)

C++类的复合和继承关系(C++继承类和封闭类的关系)

作者: Then丶 | 来源:发表于2020-06-17 21:04 被阅读0次

    编写一个小区养狗管理程序,该程序需要一个“主人”类,还需要一个“狗”类。狗是有主人的,主人也有狗。假定狗只有一个主人,但一个主人可以有最多 10 条狗。该如何处理“主人”类和“狗”类的关系呢?

    class CDog;
    class CMaster  //主人
    {
        CDog dogs[10];
        int dogNum;  //狗的数量
    };
    class CDog
    {
        CMaster m;
    };
    

    这种写法是无法通过编译的。因为尽管提前对 CDog 类进行了声明,但编译到第 4 行时,编译器还是不知道 CDog 类的对象是什么样的,所以无法编译定义 dog 对象的语句。而且这种“人中有狗,狗中有人”的做法导致了循环定义。

    避免循环定义的方法是在一个类中使用另一个类的指针,而不是对象作为成员变量

    class CDog;
    class CMaster
    {
        CDog* dogs[10];
        int dogNum;  //狗的数量
    };
    class CDog
    {
        CMaster m;
    };
    

    上面这种写法在第 4 行定义了一个 CDog 类的指针数组作为 CMaster 类的成员对象。指针就是地址,大小固定为 4 个字节,所以编译器编译到此时不需要知道 CDog 类是什么样子。

    这种写法的思想是:当一个 CMaster 对象养了一条狗时,就用 new 运算符动态分配一个 CDog 类的对象,然后在 dogs 数组中找一个元素,让它指向动态分配的 CDog 对象。

    这种写法还是不够好。问题出在 CDog 对象中包含了 CMaster 对象。在多条狗的主人相同的情况下,多个 CDog 对象中的 CMaster 对象都代表同一个主人,这造成了没有必要的冗余:一个主人用一个 CMaster 对象表示足矣,没有必要对应于多个 CMaster 对象。

    而且,在一对多这种情况下,当主人的个人信息发生变化时,就需要将与其对应的、位于多个 CDog 对象中的 CMaster 成员变量 m 都找出来修改,这毫无必要,而且非常麻烦。

    正确的写法应该是为“狗”类设一个“主人”类的指针成员变量,为“主人”类设一个“狗”类的对象数组。

    class CMaster;
    classCDog
    {
        CMaster* pm;
    };
    class CMaster
    {
        CDog dogs[10];
        int dogNum;
    };
    

    这样,主人相同的多个 CDog 对象,其 pm 指针都指向同一个 CMaster 对象。

    实际上,每个主人未必都养 10 条狗,因此出于节省空间的目的,在 CMaster 类中设置 CDog 类对象的指针数组,而不是对象数组,也是一种好的写法。

    class CMaster
    {
        CDog* dogs[10];
        int dogNum;
    };
    

    有的教材将类 A 的成员变量是类 B 的指针这种情况称为“类 A 知道类 B”,两个类之间是“知道”关系。


    原文: C++类的复合和继承关系(C++继承类和封闭类的关系)
    http://c.biancheng.net/view/251.html

    相关文章

      网友评论

          本文标题:C++类的复合和继承关系(C++继承类和封闭类的关系)

          本文链接:https://www.haomeiwen.com/subject/jalexktx.html