对象关系分析(非继承关系)

  现实环境存在各种对象关系,可以使用特殊的关系类型描述词来形容这些关系。

例如:

  1. 方形是属于形状的一种,可以用“is-a”来描述方形与形状的关系。  

  2. 汽车都有方向盘,可以用“has-a”来描述汽车与方向盘的关系。

  3. 程序员使用键盘编辑代码,可以用“uses-a”来描述程序员与键盘的关系。

  4. 花朵依赖蜜蜂传播花粉,可以使用“depends-on”来描述花朵与蜜蜂的关系。

  5. 学生是一个班级的成员,可以使用“member-of”来描述学生与班级的关系。

  6. 肢体属于人体的一部分,可以使用“part-of”来描述肢体与人体的关系。

  使用C++进行面向对象的编程过程,如果能精准的理解对象间的关系,对编写高质量的代码有很大帮助。

  下面列出几个典型的对象关系(非继承):

  一. 对象组合关系

  对象组合关系易于理解,如一辆车是由车轮、车架、发动机等设备组成的,电脑是由显示器,机箱,CPU等

设备组成的。这些关系称为组合关系(composition),而在这种情况下,整车与轮子的关系为包含(“has-a”)。

在C++中,对象组合关系能够将复杂的类转化为多个简单的类的组合,简化了复杂类的操作。

  对象组合又包含两种形式:一种是组合,另一种是聚合。

  1.  组合关系:

  满足组合关系包含下面几个前提:

  a. 成员必须是类的一部分;

  b. 成员在一个时期只能属于一个类;

  c. 成员在一个类中必须存在;

  d. 成员不必知道自身包含在某个类中。

  组合的关系尤似人体与心脏的关系,部分必须包含于整体,整体必须由部分组成,某一时刻心脏

必须属于某个人体,而不能属于其他人体。组合关系强调对象的完整性必须由成员来保证,成员与对象是单向

保证的,即对象必须包含成员,而成员不一定存在于此对象。

  class Point2D

  {

    private:

      int m_x;

      int m_y;

      ...

    public:

      ...

  }

 其中m_x、m_y与类Point2D的关系即为组合关系。

  2. 聚合关系

  满足聚合关系包含下面几个要素:

  a. 成员必须是类的一部分;

  b. 成员在一个时期可以属于多个类;

  c. 成员在类中不必一定存在;

  d. 成员不必知道自身包含在某个类中。

  同组合关系一样,聚合关系也是部分与整体的关系,但不同于组合关系,成员可以在同一时期属于多个对象,

当聚合关系对象创建或消灭时,聚合成员既不负责创建对象的部件,也不负责消除对象的部件。这好比人与家庭住址的

关系,每个人都有住址,然而这个住址可以属于多个人(父母兄弟)。人员不管理住址,事实上在人住那之前,那个地址

可能就已经存在。此外,人通常知道自己住址名称,但住址不知道谁住在该处。这里人与住址的关系就是聚合关系。

  对聚合关系进行建模时,处理对象析构时,整体对象不负责销毁聚合成员。     

  包含聚合关系的类实现同组合关系基本相同,因为它们都是属于整体部分的关系。

  在组合关系中,成员变量通常是普通变量,如果是指针,则组合类必须负责分配和释放该指针指向的空间。

  在聚合关系中,成员变量通常是引用或者指针,并且该成员变量引用的是类作用域外的对象。因此,当对象被

销毁时,其中聚合关系成员变量引用或指针将被销毁,但是引用或指向的对象仍然存在。

  如下示例,教师与教师名字是组合的关系,教师必须有名字,教师与名字共存,教师类对象销毁后,教师名字也销毁了。

而教师与部门的关系是聚合的关系,该部门可以有很多其他教师,教师也可以同时属于别的部门,该部门销毁后,教师仍然存在。

#include <string>
 
class Teacher
{
private:
    std::string m_name;
 
public:
    Teacher(std::string name)
        : m_name(name)
    {
    }
 
    std::string getName() { return m_name; }
};
 
class Department
{
private:
    Teacher *m_teacher; // This dept holds only one teacher for simplicity, but it could hold many teachers
 
public:
    Department(Teacher *teacher=NULL)
        : m_teacher(teacher)
    {
    }
};
 
int main()
{
    // Create a teacher outside the scope of the Department
    Teacher *teacher = new Teacher("Bob"); // create a teacher
    {
        // Create a department and use the constructor parameter to pass
        // the teacher to it.
        Department dept(teacher);
 
    } // dept goes out of scope here and is destroyed
 
    // Teacher still exists here because dept did not delete m_teacher
 
    std::cout << teacher->getName() << " still exists!";
 
    delete teacher;
 
    return 0;
}

 

posted @ 2017-01-10 22:06  流浪侠客  阅读(179)  评论(0编辑  收藏  举报