2010-06-28 15 views
5

यहाँ (इस कोड काम नहीं करता है) मैं क्या करने की कोशिश कर रहा हूँ है:एक व्युत्पन्न सी ++ वर्ग आधार सूचक के माध्यम से कैसे क्लोन कर सकता है?

class Base 
{ 
    virtual Base *clone() { return new Base(this); } 
    virtual void ID() { printf("BASE"); 
}; 

class Derived : publc Base 
{ 
    virtual Base *clone() { return new Derived(this); } 
    virtual void ID() { printf("DERIVED"); } 
} 

. 
. 
Derived d; 
Base *bp = &d; 
Base *bp2 = bp->clone(); 

bp2->ID(); 

मैं क्या चाहते की तरह देखने के लिए "व्युत्पन्न" बाहर मुद्रित है ... मैं क्या मिलता है "आधार "। मैं एक लंबे समय से सी प्रोग्रामर हूं, और सी ++ के साथ काफी अनुभवी हूं ... लेकिन मैं इस के साथ कोई रास्ता नहीं बना रहा हूं ... किसी भी मदद की सराहना की जाएगी।

+0

अधिक कोड दिखा रहा है, विशेष रूप से इस मामले में प्रत्येक वर्ग के सभी निर्माता महत्वपूर्ण हैं। (कुछ को आपके कोड से अनुमानित किया जा सकता है, लेकिन यह हर किसी से अधिक सही उत्तर पाने में मदद करता है ...) – Macke

+0

एचएम। प्रारंभिक कोड में आधार बीपी = और डी था। अब इसे बेस * बीपी = और डी में बदल दिया गया है; – Macke

+0

प्रश्न के लिए प्रासंगिक नहीं है, लेकिन आप कक्षाओं पर आभासी विनाशक भी चाहते हैं। –

उत्तर

0

आप slicing रहे Base bp = &d; में वर्ग (इस व्युत्पन्न-ptr से एक नया आधार बीपी निर्माण करती है।)

बजाय Base* bp = &d; की कोशिश करो। , (यानी व्युत्पन्न वस्तु को बेस प्रकार का एक सूचक बना सकते हैं।)

+1

मुझे ओपी (इस समय) पर एक संपादन कथन नहीं दिखाई देता है, और जैसा कि आप सुझाव देते हैं, कोड पहले से ही कर रहा है (हालांकि यह बिल्कुल संकलित नहीं होता है)। जबकि रिपोर्ट की गई समस्या निश्चित रूप से एक टुकड़ा करने की समस्या का पता लगाती है, पोस्ट कोड इसे प्रदर्शित नहीं करता है ... संपादित करें: ओह, मैं संपादन चिह्न के लिए गलत पोस्ट देख रहा था। आप सही हैं, मार्कस। परेशानी के लिए खेद हैं। –

1

साथ Base bp = &d;

आप "कटा हुआ" किया है d तो संकलक करने के लिए, bp वास्तव में केवल प्रकार Base की है, जिसके कारण जब आप bp->clone() पर कॉल करें कंपाइलर Base::clone(); और bp2->ID() प्रिंट BASE पर कॉल करता है।

Base& bp = d; जो भी आप चाहते हैं वह करेंगे।

0

आपका उदाहरण गलत है और संकलित नहीं होगा। विशेष रूप से इस लाइन:

Base bp = &d; 

कि यह भी आपकी समस्या का मूल कारण हो सकता है (यदि आप अपने वस्तु टुकड़ा करने की क्रिया किया जा सकता है), लेकिन मैं काम कर कोड देखे बिना कुछ के लिए नहीं बता सकता।

तुम भी एक समस्या है जहाँ आपके दो वर्गों से संबंधित नहीं कर रहे हैं (आप class Derived : public Base लिखने के लिए मतलब था?)

+0

हां, मुझे पता है कि यह कोड संकलित नहीं होगा। मैंने इसे पोस्ट करने के एक मिनट के भीतर इस बग को ठीक किया, लेकिन आप लोग तेज़ हैं! कृपया सही प्रश्न देखें। मुझे नहीं पता कि "स्लाइसिंग" क्या है, लेकिन मैं इसे देख रहा हूं ... – wanlessv

+1

@wanlessv - आपको हमेशा यह सुनिश्चित करना चाहिए कि आपका कोड एक प्रश्न पोस्ट करने से पहले संकलित हो। आप जो भी करने की कोशिश कर रहे हैं उसे जानने के बिना, हम हमेशा यह नहीं देख सकते कि समस्या क्या है। –

3

कि कोड वाक्य त्रुटियों के साथ छलनी है। शायद सबसे महत्वपूर्ण, व्युत्पन्न बेस से प्राप्त नहीं होता है। दूसरा, सिंटैक्टिकल त्रुटियों (शायद सरल टाइपो) से अलग, बेस को स्पष्ट रूप से आभासी विनाशक की आवश्यकता होती है। क्लोन विधि बहुत अधिक मांग करती है कि आप बेस पॉइंटर (बेस *) पर ऑपरेटर को हटा सकते हैं।

#include <cstdio> 

class Base 
{ 
    public: 
    Base() {} 
    Base(const Base&) {} 
    virtual Base *clone() { return new Base(*this); } 
    virtual void ID() { printf("BASE"); } 
}; 

class Derived : public Base 
{ 
    public: 
    Derived() {} 
    Derived(const Derived&) {} 
    virtual Base *clone() { return new Derived(*this); } 
    virtual void ID() { printf("DERIVED"); } 
}; 


int main() 
{ 
    Derived d; 
    Base *bp = &d; 
    Base *bp2 = bp->clone(); 

    bp2->ID(); 
} 

जो तुम देता है कि आप क्या ढूंढ रहे हैं - व्युत्पन्न:

class Base 
{ 
public: 
    virtual ~Base() {} 
    virtual Base* clone() const { return new Base(*this); } 
    virtual void ID() const { printf("BASE"); } 
}; 

class Derived: public Base 
{ 
public: 
    // [Edit] Changed return type to Derived* instead of Base*. 
    // Thanks to Matthieu for pointing this out. @see comments below. 
    virtual Derived* clone() const { return new Derived(*this); } 
    virtual void ID() const { printf("DERIVED"); } 
}; 

int main() 
{ 
    Derived d; 
    Base* bp = &d; 

    Base* bp2 = bp->clone(); 
    bp2->ID(); // outputs DERIVED as expected 
    delete bp2; 
} 
+1

मैं सभी के लिए अपील करता हूं ... मैंने एक साधारण उदाहरण बनाया और इसे वास्तविक कोड में हर किसी को दफनाने से बचने की कोशिश की, लेकिन मैंने सरल संस्करण में कई गलतियां की, और इससे पहले कि मैं वापस आ सकूं और उन्हें सही कर सकूं, मैं कई जवाब थे! इस बिंदु पर, मुझे नहीं पता कि कौन से उत्तर मेरे बग्गी उदाहरण का जवाब दे रहे हैं, जो अभी भी मेरे असली प्रश्न से संबंधित है ... – wanlessv

+0

स्मार्ट पॉइंटर (जैसे boost :: shared_ptr) का उपयोग करना बेहतर है स्वचालित रूप से बीपी 2 हटा दें। –

+0

@ डैनियल हाँ, लेकिन मुझे लगता है कि यदि ओपी को विरासत और बहुरूपता के साथ कठिनाई हो रही है, तो वह कुछ समय पहले हो सकता है कि वह आरएआईआई और स्मार्ट पॉइंटर्स को समझ सके। – stinky472

7

एक बार सभी संकलन त्रुटियों के ठीक हो, मैं इस के साथ समाप्त हो गया।

+0

आपके समय के लिए धन्यवाद। इस उदाहरण का अध्ययन करते हुए, मुझे लगता है कि मैं इस मुद्दे को समझता हूं। – wanlessv

0

कोड मूर्खतापूर्ण वाक्यविन्यास टाइपो और गायब ctors के अलावा ठीक दिखता है।

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