2011-11-06 10 views
5

मैं एक संदेह है जानने के बिना ढेर करने के लिए एक वस्तु की नकल के लिए नए ऑपरेटर का उपयोग करना, नीचे समारोह ग्रुप ए या कुछ और व्युत्पन्न प्रकार की एक वस्तु प्राप्त कर सकते हैं।अपने प्रकार

A *copyToHeap(A &obj) { 
    A *ptr=new A(obj); 
    return ptr; 
} 

अगर हम इसे इस तरह कहते हैं:

//B inherits from A 
B bObj; 
B *hPtr=copyToHeap(bObj); 

वस्तु hPtr द्वारा बताया प्रकार ए या बी की वास्तव में है? यह सुरक्षित है?

उत्तर

4

जब आप अपने कोड में नीचे कार्य करें:

A* ptr = new A(obj); 

आप हमेशा एक एक उदाहरण मिल जाएगा। ओबीजे को ए के रूप में माना जाएगा और ओबी के "ए भाग" के आधार पर एक नया ए बनाया जाएगा।

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

virtual A* MakeCopy(); 

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

5

लौटाया गया ऑब्जेक्ट pointer to A प्रकार है, जिसका अर्थ है hPtr द्वारा ऑब्जेक्ट की गई ऑब्जेक्ट A है। कॉलिंग विधियों या बी के लिए विशिष्ट सदस्यों के कारण यह सुरक्षित नहीं है क्योंकि क्रैश या अपरिभाषित व्यवहार होगा। आप शायद factory pattern खोज रहे हैं।

1

यह सुरक्षित नहीं है, यह सही नहीं है, और संकलक आप कुछ निदान देना चाहिए। क्या आपने GCC का उपयोग करते हुए g++ -Wall के साथ संकलित करने का प्रयास किया था?

+0

क्षमा करें, मैंने स्मृति से कोड लिखा है और मैं कम करने की कोशिश नहीं कर सका। – jlledom

2

एक सुरक्षित तरीका एक आभासी क्लोन विधि प्रदान करना है

#include <memory> 

class Base 
{ 
public: 
    virtual std::unique_ptr<Base> Clone() = 0; 
}; 

class Derived : public Base 
{ 
public: 
    Derived(int i) : i_(i) 
    { 

    } 

    std::unique_ptr<Base> Clone() 
    { 
     return std::unique_ptr<Derived>(new Derived(i_)); 
    } 

private: 
    int i_; 
}; 


std::unique_ptr<Base> copyToHeap(std::unique_ptr<Base> obj) 
{ 
    return obj->Clone(); 
} 
1

संकलन करता है नहीं:

B *hPtr=copyToHeap(bObj); //error: invalid conversion from ‘A*’ to ‘B*’ 

आप A* यह संकलित करने के लिए hPtr के प्रकार को बदलते हैं, लेकिन आप अभी भी एक मिल A ऑब्जेक्ट। A जो आप और एक A वस्तु पैदा करेगा का उपयोग B वस्तु जो A में परिभाषित किया गया, B हिस्सा टुकड़ा करने की क्रिया के क्षेत्र नकल के लिए डिफ़ॉल्ट कॉपी-निर्माता।

0
क्योंकि सभी इस पोस्ट में/ऊपर वर्णित समस्याओं की

- आप इसे से बचने कर सकते सब पर अगर (और मैं एक कारण है कि आप नहीं कर सकता है के बारे में सोच नहीं कर सकते हैं) - आप अपने कोड की आवश्यकता के लिए तैयार नहीं करने चाहिए "copyToHeap"।

Luchian बताते हैं के रूप में, आप शायद एक कारखाने चाहते हैं। फैक्ट्री आपके ऑब्जेक्ट को ढेर पर शुरू करने के लिए बनाता है (और ऑब्जेक्ट/पॉइंटर/मेमोरी के जीवनकाल को प्रबंधित करने के लिए एक स्मार्ट पॉइंटर देता है)।

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