2009-09-18 9 views
8

Shape.hसी ++ अधिरोहित विधि

namespace Graphics { 
class Shape { 
public: 
    virtual void Render(Point point) {}; 
}; 
} 

Rect.h

namespace Graphics { 

    class Rect : public Shape { 

    public: 

     Rect(float x, float y); 
     Rect(); 

     void setSize(float x, float y); 

     virtual void Render(Point point); 


    private: 

     float sizeX; 
     float sizeY; 

    }; 

} 

struct ShapePointPair { 
    Shape shape; 
    Point location; 
}; 

कहा जाता हो रही है नहीं इस तरह उपयोग किया:

std::vector<Graphics::ShapePointPair> theShapes = theSurface.getList(); 

for(int i = 0; i < theShapes.size(); i++) { 

    theShapes[i].shape.Render(theShapes[i].location); 

} 

इस कोड को आकार बुला समाप्त होता है :: प्रस्तुत और Rect :: रेंडर

मुझे लगता है कि यह है क्योंकि यह एक आकार में रेक्ट कास्टिंग कर रहा है, लेकिन मुझे यह नहीं पता कि इसे करने से इसे कैसे रोकें। मैं प्रत्येक आकार को नियंत्रित करने की कोशिश कर रहा हूं कि इसे रेंडर विधि को ओवरराइड करके कैसे प्रदान किया जाता है।

इसे प्राप्त करने के तरीके पर कोई विचार?

+0

शायद तुम हमें कोड कि वेक्टर तत्वों को दिखाने के लिए करना चाहते हैं? –

+1

समस्या और समाधान लगभग इस http://stackoverflow.com/questions/1230006/ प्रश्न के समान हैं। वैसे, आपके पास कंक्रीट बेस क्लास का एक वेक्टर है (कंक्रीट बेस क्लास, जिसे आप * स्लाइसिंग * व्युत्पन्न कक्षाओं द्वारा बनाते हैं यदि आप Rect :: रेंडर कहने की अपेक्षा करते हैं। –

उत्तर

19

यहाँ अपने समस्या है। आपको Shape *, या shared_ptr<Shape> या कुछ संग्रहीत करना चाहिए। लेकिन Shape नहीं; सी ++ जावा नहीं है।

जब आप आवंटित एक RectShape करने के लिए, केवल Shape भाग की नकल की जा रही है (इस टुकड़ा करने की क्रिया वस्तु है)।

+0

auto_ptr डेटा खोलेगा क्योंकि आकार – Mark

+0

@ मार्क में आकार के आकार के रूप में आकार दिया गया है: नोट। – dave4420

+1

धन्यवाद। मैं पॉइंटर्स के बिना ऐसा करने की उम्मीद कर रहा था क्योंकि आकार बहुत मेमोरी का उपयोग नहीं करते हैं, इसलिए स्टैक पर चारों ओर प्रतिलिपि बनाना आसान है, लेकिन ऐसा लगता है कि यह संभव नहीं है। त्वरित उत्तरों के लिए सभी को धन्यवाद। –

1

पॉलिमॉर्फिज्म केवल एक आकृति वस्तु से नहीं, एक सूचक से एक आकार में काम करेगा।

struct ShapePointPair { 
     Shape shape; 
     Point location; 
}; 

आप एक Shape भंडारण कर रहे हैं:

3

इस समस्या को स्लाइसिंग कहा जाता है - आधार पर प्रतिलिपि करते समय आप व्युत्पन्न कार्यक्षमता खो देते हैं। आधार वर्ग को यह उपयोग संकेत, से बचने के लिए यानी

std::vector<Graphics::Shape*> s; 
s.push_back(&some_rect); 
+0

धन्यवाद। मैंने पहले स्लाइसिंग के बारे में नहीं सुना था, अगली बार इसे ध्यान में रखेगा। –

2

समस्या यह है कि अपने वेक्टर में आप आकार वस्तुओं की प्रतियां भंडारण कर रहे हैं, और एक आकार वस्तु डेटा या उसके व्युत्पन्न वर्ग की कार्यक्षमता नकल नहीं करता है को कॉपी है - आप slicing polymorphism दूर हैं।

नए का उपयोग करके वस्तुओं को प्रबंधित करें और हटाएं, और अपने वेक्टर को पॉइंटर्स स्टोर करने के लिए व्यवस्थित करें।

1

आप ओवरराइड के लिए सीधे आकृति ऑब्जेक्ट तक पहुंच रहे हैं, आपको किसी पॉइंटर या संदर्भ के माध्यम से ऑब्जेक्ट तक पहुंचने की आवश्यकता है।

उदाहरण के लिए जब आप कोड होगा 'टुकड़ा' वस्तु ShapePointPair में आकार assigne और केवल ShapePointPair

ऐसा करने में आकार बिट कॉपी अर्थ होगा कि आप स्मृति प्रबंधन को देखने के लिए - तो आप इस्तेमाल कर सकते हैं संरचना में एक स्मार्ट पॉइंटर शेपपॉइंटपेयर { smart_pointer आकार; प्वाइंट स्थान; };

0

नहीं, यह कास्टिंग नहीं है।

आप के बजाय प्वाइंट baseclass के लिए एक संदर्भ स्टोर कर सकते हैं:

struct ShapePointPair { 
     Shape shape; 
     Point &location; 
}; 

इस संदर्भ struct ShapePointPair के लिए निर्माण समय पर सेट किया जाना चाहिए।इस उद्देश्य के लिए ShapePointPair में एक कन्स्ट्रक्टर जोड़ें। इसे संदर्भ के पारित (नव निर्मित) उदाहरणों को पारित किया जाना चाहिए।

इसके अलावा स्मृति प्रबंधन responsiblities (उचित लिखा विनाशकर्ता, आदि) का निरीक्षण।