वस्तुओं के स्वामित्व वाले लाइब्रेरी नियंत्रण सत्रों में सी एपीआई को देखते हुए, सीएआई एपीआई को आरएआईआई सी ++ कक्षाओं में समाहित करने के लिए सबसे अच्छा डिज़ाइन क्या है?RAII C++ कक्षाओं में सी एपीआई को कैसे समाहित किया जाए?
सी एपीआई लगता है:
HANDLE OpenSession(STRING sessionID);
void CloseSession(HANDLE hSession);
HANDLE OpenItem(HANDLE hSession, STRING itemID);
void CloseItem(HANDLE hItem);
प्लस अन्य कार्यों है कि इन प्रकारों में से एक (सत्र, या आइटम) के लिए उपयोगी होते हैं और प्रासंगिक वस्तु की सी ++ सदस्य कार्यों के लिए सीधे मैप करें। लेकिन उन्हें यहां जरूरी नहीं है। मेरी मुख्य रुचि इन वस्तुओं के निर्माण और विनाश में है, इन कक्षाओं के सही उद्घाटन और समापन को प्रबंधित करने के लिए आरएआईआई का उपयोग करना।
मेरी कक्षाओं के डिजाइन के लिए मेरा पहला विचार शुद्ध और प्रत्यक्ष आरएआईआई है। निहित वर्ग कंटेनर ऑब्जेक्ट को कन्स्ट्रक्टर पैरामीटर के रूप में स्वीकार करता है।
class Session {
HANDLE const m_hSession;
public:
Session(STRING sessionID): m_hSession(OpenSession(sessionID)) {}
~Session() { CloseSession(m_hSession); }
};
class Item {
HANDLE const m_hItem;
public:
Item(HANDLE hSession, STRING itemID): m_hItem(OpenItem(hSession, itemID)) {}
~Item() { CloseItem(m_hItem); }
};
इस डिजाइन एक बुरा व्यवहार की अनुमति के नुकसान है: एक सत्र वस्तु विलुप्त जा सकता है (और CloseSession समारोह कहा जाता है) से पहले अपने आइटम के सभी ऑब्जेक्ट के विलुप्त कर दिया है। यह कष्टप्रद है, क्योंकि ऐसा नहीं होना चाहिए। भले ही यह गलत व्यवहार संभव है, इसलिए सी एपीआई का उपयोग करके मान्य नहीं है, मैं इसे सी ++ एपीआई में डिज़ाइन से टालना चाहता हूं।
यही कारण है कि मैं निम्नलिखित डिजाइन का उपयोग करने के बारे में सोच रहा हूं जहां सत्र में इसके आइटम होते हैं (यह वास्तविक संबंध दिखाता है), और आइटम बनाने और नष्ट करने में सक्षम एकमात्र वर्ग है। पहले अपने आइटम बंद हो जाती हैं
class Item {
HANDLE const m_hItem;
Item(HANDLE hSession, STRING itemID): m_hItem(OpenItem(hSession, itemID) {}
~Item() { CloseItem(m_hItem); }
friend class Session;
public:
};
class Session {
HANDLE const m_hSession;
typedef vector<Item *> VecItem;
VecItem m_vecItem;
Session(STRING sessionID): m_hSession(OpenSession(sessionID)) {}
~Session() {
for (size_t n = 0 ; n < m_vecItem.size() ; ++n) delete m_vecItem[n];
m_vecItem.clear();
CloseSession(m_hSession);
}
public:
Item * OpenItem(STRING itemID) {
Item *p = new Item(m_hSession, itemID);
m_vecItem.push_back(p);
return p;
}
void CloseItem(Item * item) {
VecItem::iterator it = find(m_vecItem.begin(), m_vecItem.end(), item);
if (it != m_vecItem.end()) {
Item *p = *it; m_vecItem.erase(it); delete p;
}
}
};
यह एक ही तरीका है एक सत्र सुनिश्चित करने के लिए के रूप में मेरे लिए लग रहा है बंद कर दिया है नहीं: डिजाइन कि आइटम वस्तुओं सत्र के सदस्य हैं में परिलक्षित करती है, और इसलिए पहले विलुप्त हो जाएगा सत्र नष्ट हो गया है।
हालांकि, यह मेरे लिए थोड़ा अजीब लग रहा है, क्योंकि यह सत्र वर्ग के इंटरफ़ेस में इन कार्यों को OpenItem और CloseItem छोड़ देता है। मैं राई की रेखा में कुछ और ढूंढ रहा था (मेरे लिए, इसका मतलब है आइटम के लिए एक कन्स्ट्रक्टर का उपयोग करना), लेकिन यह कल्पना करने के लिए एक तरीका कल्पना नहीं कर सकता है कि सही विनाश आदेश सुनिश्चित करेगा।
इसके अलावा, पॉइंटर्स का उपयोग करके, नया और हटाएं बहुत पुरानी शताब्दी सी ++ है। क्लास आइटम के लिए मूव सेमेन्टिक्स को सही ढंग से परिभाषित करने की कीमत पर आइटम के एक वेक्टर (आइटम * के बजाय) का उपयोग करना संभव होना चाहिए, लेकिन यह आइटम के लिए एक डिफ़ॉल्ट कन्स्ट्रक्टर की अनुमति देने की कीमत पर होगा जो अनियमित द्वितीय श्रेणी का निर्माण करेगा नागरिक आइटम वस्तुओं।
कोई बेहतर डिजाइन विचार?
यदि हम मानते हैं कि मानक आरएआईआई रैपिंग ठीक है, तो 2 प्रश्न हैं: सत्र में आइटम खोलने/बंद करने का सबसे सुरुचिपूर्ण (आरएआईआई) तरीका क्या है और पॉइंटर्स के वेक्टर के लिए एक विकल्प क्या है, है ना? – stefaanv
आदर्श रूप से, मैं वस्तुओं को खोलने/बंद करने के लिए सुरुचिपूर्ण आरएआईआई तरीका, और सत्र से संबंधित वस्तुओं को देखना चाहता हूं ताकि वे सत्र से पहले बंद हो जाएं। (पॉइंटर्स इश्यू का वेक्टर सवाल नहीं है) –
मेरे लिए, आपके द्वारा दिखाए गए 2 उदाहरण एक अलग उद्देश्य प्रदान करते हैं चाहे आप अस्थायी आइटम (केवल एक समारोह कहने के दायरे में) के साथ काम करना चाहते हैं या यदि आप आइटम चाहते हैं लंबे समय तक रहना आरएआईआई जब तक सत्र जीवित रहता है तब तक वस्तुओं को साफ़ करने में आपकी सहायता नहीं कर सकता है। – stefaanv