कुछ उपयोगों को इकट्ठा करने की कोशिश कर रहा है:
अपने जीवनकाल को लंबा करने के लिए, संदर्भ-से-कॉन्स्टेंट के लिए कुछ अस्थायी बांधना। संदर्भ एक आधार हो सकता है - और इसके विध्वंसक को आभासी होने की आवश्यकता नहीं है - सही विध्वंसक को अभी भी कहा जाता है:
ScopeGuard const& guard = MakeGuard(&cleanUpFunction);
स्पष्टीकरण , कोड का उपयोग कर:
struct ScopeGuard {
~ScopeGuard() { } // not virtual
};
template<typename T> struct Derived : ScopeGuard {
T t;
Derived(T t):t(t) { }
~Derived() {
t(); // call function
}
};
template<typename T> Derived<T> MakeGuard(T t) { return Derived<T>(t); }
इस ट्रिक का उपयोग अलेक्जेंड्रेस्कु के स्कोपगार्ड उपयोगिता वर्ग में किया जाता है। एक बार अस्थायी दायरे से बाहर हो जाने पर, व्युत्पन्न के विध्वंसक को सही ढंग से कहा जाता है। उपरोक्त कोड कुछ छोटे विवरणों को याद करता है, लेकिन इसके साथ बड़ी बात है।
दूसरों को यह बताने के लिए कि इस विधि की तार्किक स्थिति नहीं बदलेगी, का उपयोग करें।
struct SmartPtr {
int getCopies() const { return mCopiesMade; }
};
कॉपी-ऑन-राइट कक्षाओं के लिए कास्ट का उपयोग करें , कंपाइलर को यह तय करने में मदद करें कि आपको कब और कब कॉपी करने की आवश्यकता नहीं है।
struct MyString {
char * getData() { /* copy: caller might write */ return mData; }
char const* getData() const { return mData; }
};
स्पष्टीकरण : आप डेटा साझा करना चाहते हैं जब आप कुछ कॉपी कर सकते हैं जब तक कि मूल रूप से और कोपीईड ऑब्जेक्ट का डेटा समान रहेगा। एक बार जब कोई ऑब्जेक्ट डेटा बदलता है, तो आपको अभी दो संस्करणों की आवश्यकता होती है: एक मूल के लिए, और एक कॉपी के लिए। यही है, आप किसी भी ऑब्जेक्ट पर लिखने पर कॉपी करते हैं, ताकि वे अब दोनों का अपना संस्करण हो।
कोड का उपयोग करना :
int main() {
string const a = "1234";
string const b = a;
// outputs the same address for COW strings
cout << (void*)&a[0] << ", " << (void*)&b[0];
}
उपरोक्त स्निपेट मेरे GCC पर एक ही पता छापता है, क्योंकि प्रयुक्त C ++ लाइब्रेरी कॉपी-ऑन-राइट को लागू करता है std::string
। दोनों स्ट्रिंग्स, भले ही वे अलग-अलग ऑब्जेक्ट हों, अपने स्ट्रिंग डेटा के लिए समान मेमोरी साझा करते हैं। b
नॉन-कास्ट बनाना गैर-कास्ट संस्करण को पसंद करेगा operator[]
और जीसीसी बैकिंग मेमोरी बफर की एक प्रति बनाएगा, क्योंकि हम इसे बदल सकते हैं और इसे डेटा को प्रभावित नहीं करना चाहिए a
!
int main() {
string const a = "1234";
string b = a;
// outputs different addresses!
cout << (void*)&a[0] << ", " << (void*)&b[0];
}
कॉपी-कंस्ट्रक्टर के लिए कांस्टेबल ऑब्जेक्ट्स और टेम्परेरी से कॉपी बनाना :
struct MyClass {
MyClass(MyClass const& that) { /* make copy of that */ }
};
स्थिरांक बनाने के लिए जो तुच्छ रूप से बदल नहीं सकते हैं
double const PI = 3.1415;
मूल्य के बजाय संदर्भ द्वारा मनमानी वस्तुओं को पारित करने के लिए - संभवतः महंगा या असंभव द्वारा पारित मूल्य को रोकने के लिए
void PrintIt(Object const& obj) {
// ...
}