2012-03-27 15 views
18

में क्लास कॉपी कन्स्ट्रक्टर वर्चुअल बना सकते हैं क्या हम सी ++ में क्लास कॉपी कन्स्ट्रक्टर वर्चुअल बना सकते हैं? कैसे इस्तेमाल करे?क्या हम सी ++

+4

मान लीजिए कि आप ... किस प्रकार निर्माता को कॉल भेजा जाना चाहिए? –

+1

http://stackoverflow.com/questions/733360/why-do-we-not-have-a-virtual-constructor-in-c –

+0

@ डेविडरोड्रिगुएज़-ड्राईबीस का डुप्लिकेट: यह एक अच्छा बिंदु है। मुझे लगता है कि यह एक जवाब होना चाहिए, क्योंकि यह – Nawaz

उत्तर

18

नहीं, आप नहीं कर सकते हैं, निर्माता वर्चुअल नहीं हो सकते हैं।

सी ++ 03 - 12.1 कंस्ट्रक्टर्स

4) एक निर्माता नहीं होगा virtual (10.3) या static (9.4)। [...]

यदि आपको ऐसा कुछ चाहिए तो आप आभासी कन्स्ट्रक्टर मुहावरे here देख सकते हैं।

+0

आपका लिंक – Arne

+0

@Arne इसे इंगित करने के लिए धन्यवाद है। मैंने लिंक अपडेट किया है। –

+0

इसे अद्यतन करने के लिए धन्यवाद। – Arne

0

कभी नहीं, यह सी ++ में संभव नहीं होगा।

1

नहीं सी ++ स्थैतिक टाइप की गई भाषा होने के नाते, सी ++ कंपाइलर को ऑब्जेक्ट पॉलीमोर्फिक रूप से बनाने के लिए व्यर्थ है। ऑब्जेक्ट बनाने के लिए संकलक वर्ग प्रकार के बारे में अवगत होना चाहिए। दूसरे शब्दों में, सी ++ कंपाइलर परिप्रेक्ष्य से संकलित समय निर्णय किस प्रकार का ऑब्जेक्ट बनाया जाना है। अगर हम कन्स्ट्रक्टर वर्चुअल बनाते हैं, तो कंपाइलर एक त्रुटि झंडे बनाता है।

+1

पूरी तरह से सच नहीं है, सार कारखाना पैटर्न देखें। –

5

नहीं आप नहीं कर सकते।

इसके अलावा, पूरी अवधारणा को समझ में नहीं आता है। वर्चुअल फ़ंक्शन वे कार्य होते हैं जो किसी ऑब्जेक्ट (ऑब्जेक्ट का गतिशील प्रकार) के मान के आधार पर प्रेषित होते हैं। जब एक कन्स्ट्रक्टर कहा जाता है, तो ऑब्जेक्ट का अभी तक कोई मान नहीं है (क्योंकि यह अभी तक नहीं बनाया गया है)। इसलिए, कोई आभासी प्रेषण संभवतः नहीं हो सकता है।

इसके बारे में सोचो। इस तरह के एक कन्स्ट्रक्टर के अर्थशास्त्र क्या होगा?

1

आप ऐसा नहीं कर सकते क्योंकि निर्माता को नए प्रकार के आकार के आधार पर कॉलर को आवंटित करने से पहले आवंटित किया जाता है, प्रतिलिपि नहीं है। और यदि यह काम करता है तो यह एक विशेष मामला होगा जो कई भाषा संरचनाओं के लिए उलटा बहुरूपता है।

लेकिन इसका मतलब यह नहीं है कि यह थोड़ा सी ++ जादू के साथ नहीं किया जा सकता है। :)

कुछ ऐसे मामले हैं जहां यह अविश्वसनीय रूप से सहायक है, उदाहरण के लिए गैर-पीओडी कक्षाओं को क्रमबद्ध करना। यह उदाहरण वर्चुअल कॉपी कन्स्ट्रक्टर बनाता है जो प्लेसमेंट का उपयोग करके काम करता है।

चेतावनी: यह एक ऐसा उदाहरण है जो विशिष्ट समस्याओं वाले कुछ उपयोगकर्ताओं की सहायता कर सकता है। सामान्य उद्देश्य कोड में ऐसा मत करो। यदि नई कक्षा के लिए आवंटित स्मृति व्युत्पन्न वर्ग से छोटी है तो यह दुर्घटनाग्रस्त हो जाएगा। इसका उपयोग करने का सबसे अच्छा (और केवल) सुरक्षित तरीका यह है कि यदि आप अपनी खुद की कक्षा मेमोरी का प्रबंधन कर रहे हैं और प्लेसमेंट का उपयोग कर रहे हैं।

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

    VirtualBase(const VirtualBase& copy) 
    { 
     copy.VirtualPlacementCopyConstructor(this); 
    } 

    virtual void VirtualPlacementCopyConstructor(void*) const {} 
}; 

class Derived :: public VirtualBase 
{ 
public: 
    ... 

    Derived(const Derived& copy) : ... don't call baseclass and make an infinite loop 
    { 
    } 

protected: 
    void VirtualPlacementCopyConstructor(void* place) const 
    { 
     new (place) Derived(*this); 
    } 
}; 
+0

यह संकलित नहीं होगा, भले ही आप इसे संकलित करने के लिए इसे ठीक करते हैं, फिर भी कार्यान्वयन पूरी तरह टूटा हुआ है। 'व्युत्पन्न' के सभी सदस्य डबल प्रारंभिकरण से ग्रस्त होंगे। यह कुछ सरल प्रकारों के साथ काम करने के लिए हो सकता है, लेकिन स्पष्ट रूप से अपरिभाषित व्यवहार में परिणाम होता है। "कन्स्ट्रक्टर" को वर्चुअलप्लेसमेंट कॉपी कंट्रोलर (वर्चुअलबेस * प्लेस) कॉन्स {ऑटो डी = डायनामिक_कास्ट (प्लेस) होना चाहिए; अगर (डी) {डी-> ~ व्युत्पन्न(); नया (डी) व्युत्पन्न (* यह); }} ' –

+0

अब यह स्पष्ट होना चाहिए कि समस्या क्या है: 'वर्चुअलप्लेसमेंट कॉपी कंट्रोलर' को बहुत जल्दी शुरू किया जाता है, जब कॉपी-इन क्लास का प्रकार अभी तक 'व्युत्पन्न' नहीं होता है। इस प्रकार विनाशक सही चीज़ नहीं करेगा, और आपको अपरिभाषित व्यवहार बहुत अधिक मिलता है। यदि आप 'static_cast' के साथ' dynamic_cast' को प्रतिस्थापित करते हैं, तो चीजें पीओडी प्रकारों के लिए काम करती हैं, और यह इसके बारे में है। जैसे ही आप जोड़ते हैं उदा। एक 'std :: string' सदस्य, सामान टूट जाएगा (बदतर अभी तक: यह हमेशा नहीं टूट जाएगा, इसलिए आप अपने बालों को खींचेंगे)। –

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