3.7 将单向关联改为双向

【1】单向、双向关联

单向和双向关联的区别:两个类是否需要互相知道。

如果类A需要知道类B,而类B也需要知道类A,那么这两个类就应该是双向关联的。如果类A只需要知道类B,而类B不需要知道类A,那么就是单向关联。

【2】将单向关联改为双向

范例:

2.1 order类

order.h

 1 #ifndef ORDER
 2 #define ORDER
 3 
 4 #include <QString>
 5 #include "customer.h"
 6 
 7 // 订单类
 8 class Order
 9 {
10 public:
11     Order(int nId = 1, QString name = QString(), Customer* pCustomer = NULL);
12 
13     int getId();
14     void setId(int nId);
15     QString getName();
16     void setName(QString name);
17     // 获取订单的客户对象
18     Customer* getCustomer();
19     // 设置订单的客户对象
20     void setCustomer(Customer *pObj);
21 
22 private:
23     int m_nId;
24     QString m_name;
25     Customer *m_pCustomer;
26 };
27 
28 #endif // ORDER

order.cpp

 1 #include "order.h"
 2 
 3 // 订单类
 4 Order::Order(int nId, QString name, Customer* pCustomer)
 5     : m_nId(nId)
 6     , m_name(name)
 7     , m_pCustomer(pCustomer)
 8 {
 9     if (m_pCustomer)
10     {
11         m_pCustomer->friendOrders().insert(m_nId);
12     }
13 }
14 
15 int Order::getId()
16 {
17     return m_nId;
18 }
19 void Order::setId(int nId)
20 {
21     m_nId = nId;
22 }
23 QString Order::getName()
24 {
25     return m_name;
26 }
27 void Order::setName(QString name)
28 {
29     m_name = name;
30 }
31 
32 // 获取订单的客户对象
33 Customer* Order::getCustomer()
34 {
35     return m_pCustomer;
36 }
37 
38 // 设置订单的客户对象
39 void Order::setCustomer(Customer *pObj)
40 {
41     if (m_pCustomer == pObj)
42     {
43         return; // 如果订单的客户本来就是pObj,那么直接退出。
44     }
45 
46     if (m_pCustomer != NULL)
47     {
48         m_pCustomer->friendOrders().remove(m_nId); // 从原客户的订单集合中删除这个订单项
49     }
50     m_pCustomer = pObj;  // 更换客户对象
51     if (m_pCustomer != NULL)
52     {
53         m_pCustomer->friendOrders().insert(m_nId); // 在新客户的订单集合中添加这个订单项
54     }
55 }

 2.2 customer类

customer.h

 1 #ifndef CUSTOMER
 2 #define CUSTOMER
 3 
 4 #include <QString>
 5 #include <QSet>
 6 
 7 class Order;
 8 // 客户类
 9 class Customer
10 {
11 public:
12     Customer(QString name = QString("sys"));
13     // 获取客户的订单集合
14     QSet<int>& friendOrders();
15 
16     // 获取客户名称
17     QString getName();
18     // 设置客户名称
19     void setName(QString name);
20 
21     void addOrder(Order* pOrder);
22 private:
23     QString m_name;
24     QSet<int> m_orders;
25 };
26 #endif // CUSTOMER

 customer.cpp

 1 #include "customer.h"
 2 #include "order.h"
 3 
 4 // 客户类
 5 // 获取客户的订单集合
 6 Customer::Customer(QString name) : m_name(name)
 7 {
 8 }
 9 
10 QSet<int>& Customer::friendOrders()
11 {
12     return m_orders;
13 }
14 
15 // 获取客户名称
16 QString Customer::getName()
17 {
18     return m_name;
19 }
20 
21 // 设置客户名称
22 void Customer::setName(QString name)
23 {
24     m_name = name;
25 }
26 
27 // 添加订单项
28 void Customer::addOrder(Order* pOrder)
29 {
30     if (pOrder != NULL)
31     {
32         pOrder->setCustomer(this);
33     }
34 }

 2.3 main函数

 1 #include "customer.h"
 2 #include "order.h"
 3 
 4 void main()
 5 {
 6     Customer* pCustomerLiu = new Customer("liu");
 7     QList<Order*> orders;
 8     for (int i = 0; i < 10; ++i)
 9     {
10         // 创建10个订单,使其客户对象均为liu
11         orders.append(new Order(i + 1, QString("item%1").arg(i + 1), pCustomerLiu));
12     }
13 
14     Customer* pCustomerSun = new Customer("sun");
15     orders.back()->setCustomer(pCustomerSun); // 最后一个订单的客户对象修改为sun
16 
17     Customer* pCustomerQin = new Customer("qin");
18     orders.at(0)->setCustomer(pCustomerQin); // 第一个订单的客户对象修改为qin
19 
20     Order* pNewOrder = new Order(110, QString("item110"), NULL);
21     pNewOrder->setCustomer(pCustomerQin); // 新建一个订单,设置其客户对象为qin
22 }

【3】总结

两个类都需要使用对方特性,但其间只有一条单向连接。添加一个反向指针,并使修改函数能够同时更新两条连接。

Good Good Study, Day Day Up.

顺序 选择 循环 总结

原文地址:https://www.cnblogs.com/Braveliu/p/7357305.html