ऑपरेटर नया () डिफॉल्ट कंस्ट्रक्टर के अस्तित्व के आधार पर ऑपरेटर डिलीट () डिलीट होने पर अलग तरीके से व्यवहार करता है


17

ऑपरेटर के साथ वर्ग सी की एक नई वस्तु बनाना () यहाँ एक त्रुटि देता है:

class C
{
public:
    C() {}
    virtual ~C() {}

    void operator delete(void*) = delete;
};


int main()
{
    C* c = new C;
}

साथ में C2280: 'void C::operator delete(void *)': function was explicitly deleted

लेकिन जब मैं बदलने के C() {} साथ C() = default; या तो यह है कि संकलक एक डिफ़ॉल्ट निर्माता (जो मेरा मानना है कि के साथ एक ही प्रभाव पड़ता है सम्मिलित करता है लाइन को हटाने = default), कोड संकलन और रन होगा।

कंपाइलर-जनरेटेड डिफॉल्ट कंस्ट्रक्टर और यूज़र-डिफ़ाइंड डिफॉल्ट कंस्ट्रक्टर के बीच क्या अंतर हैं जो ऐसा करते हैं?

मुझे इस पोस्टिंग में कुछ संकेत मिले , लेकिन क्लास सी यहाँ (उपयोगकर्ता द्वारा प्रदान किए गए निर्माता के बिना) तुच्छ नहीं है क्योंकि विध्वंसक आभासी है, है ना?

नवीनतम विज़ुअल स्टूडियो के साथ संकलित, सी ++ 17।


3
निश्चित नहीं है, लेकिन मुझे लगता है कि अंतर यह है कि डिफ़ॉल्ट रूप से निर्माणकर्ता हैnoexcept
सेबस्टियन रेडल

1
जी ++ के साथ पुन: पेश नहीं किया जा सकता। इसी तरह के निदान के बारे में operator delete()कि क्या कंस्ट्रक्टर मैन्युअल रूप से लिखा गया है या अंतर्निहित रूप से उत्पन्न हुआ है। जो मेरी उम्मीदों के अनुरूप है - चूंकि एक अपवाद को newअभिव्यक्ति द्वारा फेंक दिया जा सकता है , इसलिए कंपाइलर को एक्सेस करने की आवश्यकता है operator delete()
पीटर

@SebastianRedl आप सही हैं, जोड़ने noexceptसे कोड संकलित हो जाएगा, लेकिन कैसे ...?
येश्झो

1
@Peter अपवाद केवल कंस्ट्रक्टर द्वारा फेंका जा सकता है, इसलिए यदि यह noexceptसेबस्टियनरेडल के रूप में उल्लिखित है, तो कॉल करने की operator deleteआवश्यकता नहीं है। इसके अलावा जी ++ केवल शिकायत करता है अगर विध्वंसक आभासी है। अन्यथा यह हमेशा संकलित करता है, भले ही कंस्ट्रक्टर फेंक रहा हो।
अखरोट

@LeDYoM आपका लिंक IP पते को पार्स करने के बारे में है, जो प्रश्न के लिए अप्रासंगिक लगता है। क्या आपने कोई गलत लिंक पोस्ट किया है?
LF

जवाबों:


17

कंपाइलर-जनरेटेड डिफॉल्ट कंस्ट्रक्टर और यूज़र-डिफ़ाइंड डिफॉल्ट कंस्ट्रक्टर के बीच क्या अंतर हैं जो ऐसा करते हैं?

newअभिव्यक्ति संबंधित को आमंत्रित करती है operator newऔर फिर कंस्ट्रक्टर को कॉल करती है। यदि निर्माणकर्ता अपवाद को फेंकता है, तो संबंधित को कॉल करके (लीक मेमोरी से बचने के लिए) newप्रभाव को पूर्ववत करना होगा । यदि बाद वाला हटा दिया गया है तो अभिव्यक्ति इसे कॉल नहीं कर सकती है जिसके परिणामस्वरूप संकलक है ।operator newoperator deletenewerror: use of deleted function 'static void C::operator delete(void*)'

एक noexceptकंस्ट्रक्टर संभवतः एक अपवाद नहीं फेंक सकता है, इसलिए, operator deleteयह आवश्यक नहीं है क्योंकि यह एक newअभिव्यक्ति द्वारा नहीं बुलाया जाएगा । एक defaultतुच्छ वर्ग का एक noexceptनिर्माता भी एक निर्माता है। एक वर्चुअल डिस्ट्रक्टर की उपस्थिति को operator deleteनॉन-डिलीट करने की आवश्यकता होती है क्योंकि डिस्चार्ज को नष्ट करने वाला विशेष स्केलर ( deleteबेस क्लास पॉइंटर के माध्यम से एक्सप्रेशन को इनेबल करने के लिए एक इम्प्लीमेंटेशन डिटेल ) operator delete

यह C ++ मानक द्वारा अनिर्दिष्ट प्रतीत होता है कि क्या संकलक को operator deleteगैर-हटाए जाने की आवश्यकता है, भले ही इसे संभवतः newअभिव्यक्ति के रूप में नहीं बुलाया जा सके । gccहालाँकि, अगर यह d ( बग रिपोर्ट पोस्ट किया गया है ) अभिव्यक्ति में संबंधित operator deleteको लागू नहीं करता है ।newdelete

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.