【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.
顺序 选择 循环 总结