ढेर पर एक वस्तु को कैसे बनाया जा सकता है?

क्या कोई जानता है कि मैं कैसे कर सकता हूं, मंच-स्वतंत्र सी ++ कोड में एक वस्तु को ढेर पर बनाए जाने से रोकती है? यही है, एक वर्ग "फू" के लिए, मैं उपयोगकर्ताओं को ऐसा करने से रोकना चाहता हूं:

Foo *ptr = new Foo;

और केवल उन्हें ऐसा करने की अनुमति दें:

Foo myfooObject;

क्या किसी के पास कोई विचार है?

चीयर्स,

0
ro fr bn
रिवर्स, जो पाठकों के लिए भी दिलचस्प हो सकता है: stackoverflow.com/questions/124880/…
जोड़ा लेखक kevinarpe, स्रोत
तुमने ऐसा क्यों करना चाहोगे?
जोड़ा लेखक David Rodríguez - dribeas, स्रोत

9 उत्तर

आप फू क्लास के अंदर "ऑपरेटर न्यू" नामक एक फ़ंक्शन घोषित कर सकते हैं जो नए के सामान्य रूप तक पहुंच को अवरुद्ध कर देगा।

क्या आप इस प्रकार का व्यवहार चाहते हैं?

0
जोड़ा

आप इसे एक इंटरफ़ेस के रूप में घोषित कर सकते हैं और कार्यान्वयन कक्षा को सीधे अपने कोड से नियंत्रित कर सकते हैं।

0
जोड़ा

मुझे नहीं पता कि यह कैसे विश्वसनीय और पोर्टेबल तरीके से करना है .. लेकिन ..

यदि ऑब्जेक्ट स्टैक पर है तो आप कन्स्ट्रक्टर के भीतर जोर दे सकते हैं कि 'यह' का मान हमेशा स्टैक पॉइंटर के करीब है। एक अच्छा मौका है कि अगर यह मामला है तो ऑब्जेक्ट स्टैक पर होगा।

मेरा मानना ​​है कि सभी प्लेटफॉर्म एक ही दिशा में अपने ढेर को लागू नहीं करते हैं, इसलिए आप एक-एक-एक परीक्षण करना चाहेंगे जब ऐप यह सत्यापित करना शुरू कर देता है कि स्टैक किस तरह बढ़ता है .. या कुछ झगड़ा करें:

FooClass::FooClass() {
    char dummy;
    ptrdiff_t displacement = &dummy - reinterpret_cast(this);
    if (displacement > 10000 || displacement < -10000) {
        throw "Not on the stack - maybe..";
    }
}
0
जोड़ा
@ वर्गास - मैं असहमत हूं। 'डमी' हमेशा ढेर पर होगा, क्योंकि यह एक स्वचालित स्थानीय चर है। यह पॉइंटर या तो स्टैक को इंगित कर सकता है (यदि FooClass को स्थानीय चर के रूप में उपयोग किया जाता है) या ढेर (यदि FooClass को ढेर पर आवंटित किया जाता है, या उस वर्ग के भीतर समेकित किया जाता है जिसे ढेर पर आवंटित किया जाता है )।
जोड़ा लेखक pauldoo, स्रोत
मुझे लगता है कि यह और डमी हमेशा एक-दूसरे के करीब रहेंगे, भले ही वे ढेर में हों या ढेर में हों
जोड़ा लेखक Vargas, स्रोत
आप सही हैं, मैं सदस्य चर के लिए डमी गलत कर रहा था ... क्षमा करें
जोड़ा लेखक Vargas, स्रोत
दिलचस्प दृष्टिकोण!
जोड़ा लेखक hackworks, स्रोत

@Nick

इसे फू से प्राप्त या एकत्रित करने वाली कक्षा बनाने के द्वारा बाधित किया जा सकता है। मुझे लगता है कि मैं क्या सुझाव देता हूं (मजबूत नहीं होने पर) अभी भी व्युत्पन्न और एकत्रित कक्षाओं के लिए काम करेगा।

उदा:

struct MyStruct {
    Foo m_foo;
};

MyStruct* p = new MyStruct();

यहां मैंने फू के छिपे हुए नए ऑपरेटर को छोड़कर, ढेर पर 'फू' का एक उदाहरण बनाया है।

0
जोड़ा
+1 अच्छा चाल! टाइप कास्टिंग भी मदद कर सकते हैं
जोड़ा लेखक Viet, स्रोत

सुनिश्चित नहीं है कि यह किसी भी संकलन-समय के अवसर प्रदान करता है, लेकिन क्या आपने अपनी कक्षा के लिए 'नया' ऑपरेटर ओवरलोड करना देखा है?

0
जोड़ा

Nick's answer is a good starting point, but incomplete, as you actually need to overload:

private:
    void* operator new(size_t);         //standard new
    void* operator new(size_t, void*);  //placement new
    void* operator new[](size_t);       //array new
    void* operator new[](size_t, void*);//placement array new

(अच्छा कोडिंग अभ्यास सुझाव देगा कि आपको हटाना अधिभारित करना चाहिए और [] ऑपरेटरों को हटा देना चाहिए - मैं चाहता हूं, लेकिन चूंकि उन्हें कॉल नहीं किया जा रहा है, यह वास्तव में आवश्यक नहीं है।)

Pauldoo is also correct that this doesn't survive aggregating on Foo, although it does survive inheriting from Foo. You could do some template meta-programming magic to HELP prevent this, but it would not be immune to "evil users" and thus is probably not worth the complication. Documentation of how it should be used, and code review to ensure it is used properly, are the only ~100% way.

0
जोड़ा
क्या एक सार्वजनिक कंस्ट्रक्टर एक सार्वजनिक स्थैतिक फैक्ट्री विधि (रिटर्न-बाय-वैल्यू) के साथ संयुक्त होगा, वही पूरा करेगा?
जोड़ा लेखक kevinarpe, स्रोत
@kevinarpe यह इस बात पर निर्भर करता है कि सचमुच हम सवाल कैसे पढ़ रहे हैं। यदि आपने ऐसा किया है तो प्रश्न से सटीक कोड Foo myfooObject; संकलित नहीं होगा। मैंने कहा कि यदि आप वस्तुओं को कैसे बनाए जाते हैं, इस पर नियंत्रण करने की कोशिश कर रहा हूं, तो मैं एक दृष्टिकोण को और अधिक पसंद करता हूं।
जोड़ा लेखक Patrick Johnmeyer, स्रोत

आप फू के लिए नया अधिभार कर सकते हैं और इसे निजी बना सकते हैं। इसका मतलब यह होगा कि संकलक moan ... जब तक आप Foo के भीतर से ढेर पर फू का एक उदाहरण बना रहे हैं। इस मामले को पकड़ने के लिए, आप बस फू की नई विधि नहीं लिख सकते थे और फिर लिंकर अपरिभाषित प्रतीकों के बारे में चिंतित होगा।

class Foo {
private:
  void* operator new(size_t size);
};

पुनश्च। हाँ, मुझे पता है कि इसे आसानी से घुमाया जा सकता है। मैं वास्तव में इसकी सिफारिश नहीं कर रहा हूं - मुझे लगता है कि यह एक बुरा विचार है - मैं सिर्फ सवाल का जवाब दे रहा था! ;-)

0
जोड़ा

चूंकि डीबग हेडर ऑपरेटर को नए हस्ताक्षर ओवरराइड कर सकते हैं, इसलिए पूर्ण उपाय के रूप में हस्ताक्षर ... का उपयोग करना सबसे अच्छा है:

private:
void* operator new(size_t, ...) = delete;
void* operator new[](size_t, ...) = delete;
0
जोड़ा

इसे रचनाकारों को निजी बनाकर और स्टैक में ऑब्जेक्ट बनाने के लिए एक स्थिर सदस्य प्रदान करके रोका जा सकता है

Class Foo
{
    private:
        Foo();
        Foo(Foo& );
    public:
        static Foo GenerateInstance() { 
            Foo a ; return a; 
        }
}

यह हमेशा ढेर में वस्तु का निर्माण करेगा।

0
जोड़ा