1. 程式人生 > >3.7 將單向關聯改為雙向

3.7 將單向關聯改為雙向

同時 qstring for name 總結 class n) private urn

【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.

順序 選擇 循環 總結

3.7 將單向關聯改為雙向