2008-09-24 7 views
34

मैं यह सुनिश्चित करना चाहता हूं कि मेरी आरएआईआई कक्षा हमेशा ढेर पर आवंटित की जाए।मैं कक्षा को 'नए' ऑपरेटर के माध्यम से आवंटित करने से कैसे रोकूं? (मैं यह सुनिश्चित करना चाहता हूं कि मेरी आरएआईआई कक्षा हमेशा ढेर पर आवंटित की जाती है।)

मैं कक्षा को 'नए' ऑपरेटर के माध्यम से आवंटित करने से कैसे रोकूं?

उत्तर

45

तुम सब करने की ज़रूरत वर्ग 'नए ऑपरेटर निजी:

class X 
{ 
    private: 
     // Prevent heap allocation 
     void * operator new (size_t); 
     void * operator new[] (size_t); 
     void operator delete (void *); 
     void operator delete[] (void*); 

    // ... 
    // The rest of the implementation for X 
    // ... 
}; 

मेकिंग' घोषित है 'का उपयोग करने से निजी प्रभावी रूप से कक्षा के बाहर कोड से बचाता है' ऑपरेटर नए नए 'एक्स

का एक उदाहरण बनाने के लिए

चीजों को पूरा करने के लिए, आपको 'ऑपरेटर डिलीट' और दोनों ऑपरेटरों के सरणी संस्करणों को छिपाना चाहिए।

के बाद से सी ++ 11 तुम भी स्पष्ट रूप से कार्य करता है हटा सकते हैं:

class X 
{ 
// public, protected, private ... does not matter 
    static void *operator new  (size_t) = delete; 
    static void *operator new[] (size_t) = delete; 
    static void operator delete (void*) = delete; 
    static void operator delete[](void*) = delete; 
}; 

संबंधित प्रश्न:Is it possible to prevent stack allocation of an object and only allow it to be instiated with ‘new’?

+3

एक और मुद्दा यह है कि यह केवल श्रेणी के पदानुक्रम के बाहर से 'नया' कहलाता है। अर्थात।'एक्स' के सदस्य के लिए funciton को कॉल करना संभव है। नई सी ++ '0 एक्स फीचर "= डिलीट" आपको फ़ंक्शन को कभी भी कॉल करने से स्पष्ट रूप से रोकने की अनुमति देगी। –

+6

रिचर्ड, नहीं, इन विधियों को कभी भी नहीं कहा जा सकता क्योंकि उन्हें केवल घोषित किया गया है लेकिन परिभाषित नहीं किया गया है। अंतर यह है कि निजी पहुंच एक कंपाइलर त्रुटि के बजाय एक लिंकर त्रुटि उत्पन्न करेगा। –

+1

यह 'एक्स * एक्स = :: नया एक्स;' को रोकता नहीं है, जो स्पष्ट रूप से वैश्विक ऑपरेटर को कॉल करता है, न कि क्लास ऑपरेटर नया ... –

6

मैं आपकी प्रेरणा के प्रति आश्वस्त नहीं हूँ।

मुफ्त स्टोर पर आरएआईआई कक्षाएं बनाने के अच्छे कारण हैं।

उदाहरण के लिए, मेरे पास आरएआईआई लॉक क्लास है। मेरे पास कोड के माध्यम से एक रास्ता है जहां लॉक केवल तभी जरूरी है जब कुछ स्थितियां हों (यह एक वीडियो प्लेयर है, और मुझे केवल मेरे रेंडर लूप के दौरान लॉक पकड़ने की आवश्यकता है यदि मुझे वीडियो लोड हो गया है और खेल रहा है; अगर कुछ भी लोड नहीं हुआ है, मुझे इसकी आवश्यकता नहीं है)। मुफ्त स्टोर पर लॉक बनाने की क्षमता (scoped_ptr/auto_ptr के साथ) इसलिए बहुत उपयोगी है; यह मुझे एक ही कोड पथ का उपयोग करने की इजाजत देता है चाहे मुझे लॉक निकालना है या नहीं।

यानी कुछ इस तरह:

auto_ptr<lock> l; 
if(needs_lock) 
{ 
    l.reset(new lock(mtx)); 
} 
render(); 

यदि मैं केवल स्टैक पर ताले बना सकते हैं, मुझे लगता है कि .... नहीं कर सका

+0

एक दिलचस्प बिंदु। इसके लिए मैं आपको +1 देता हूं। ध्यान दें कि कुछ स्थितियां हैं जहां आरएआईआई मुहावरे जरूरी नहीं है। वैसे भी, शायद आपके दुविधा तक पहुंचने का एक बेहतर तरीका है अपने लॉक कन्स्ट्रक्टर में पैरामीटर जोड़ना जो इंगित करता है कि लॉक की आवश्यकता है या नहीं। – Kevin

+0

उदाहरण के लिए: वर्ग ताला { म्युटेक्स & m; bool dolock; सार्वजनिक: ताला (म्युटेक्स और M_, bool dolock_): मीटर (M_), dolock (dolock_) {if (dolock) m.lock(); } ~ लॉक() {if (dolock) m.unlock(); } }; फिर आप लिख सकते हैं: लॉक एल (mtx, need_lock); प्रस्तुत करना(); – Kevin

+0

मैं 'अतिरिक्त पैरामीटर' मार्ग लेता हूं और कक्षा को वैकल्पिक लॉक कहता हूं ... –

2

@DrPizza:

है कि आपके पास एक दिलचस्प बिंदु है। ध्यान दें कि कुछ स्थितियां हैं जहां आरएआईआई मुहावरे जरूरी नहीं है।

वैसे भी, शायद आपके दुविधा तक पहुंचने का एक बेहतर तरीका है अपने लॉक कन्स्ट्रक्टर को पैरामीटर जोड़ना जो इंगित करता है कि लॉक की आवश्यकता है या नहीं। उदाहरण के लिए:

class optional_lock 
{ 
    mutex& m; 
    bool dolock; 

public: 
    optional_lock(mutex& m_, bool dolock_) 
     : m(m_) 
     , dolock(dolock_) 
    { 
     if (dolock) m.lock(); 
    } 
    ~optional_lock() 
    { 
     if (dolock) m.unlock(); 
    } 
}; 

तो फिर तुम लिख सकते हैं:

optional_lock l(mtx, needs_lock); 
render(); 
0

मेरी विशेष स्थिति में, यदि ताला आवश्यक म्युटेक्स भी मौजूद नहीं है नहीं है, इसलिए मुझे लगता है कि दृष्टिकोण के बजाय होगा फिट करने के लिए कठिन है।

मुझे लगता है कि मैं वास्तव में समझने के लिए संघर्ष कर रहा हूं यह है कि इन वस्तुओं के निर्माण को नि: शुल्क स्टोर पर प्रतिबंधित करने का औचित्य है।

+1

औचित्य यह है कि यह नियम को लागू करने में मदद करने का एक तरीका है ताकि आने वाला अगला डेवलपर गलती से लॉक को हटाना भूल जाए (जो लॉकअप का कारण बनता है)। – Kevin

संबंधित मुद्दे

 संबंधित मुद्दे