2010-05-29 56 views
14

सी ++ में एक अमूर्त वर्ग को कैसे बनाएं, जिसमें कुछ सार तत्वों के साथ मैं एक सबक्लास में ओवरराइड करना चाहता हूं? .h फ़ाइल को कैसे दिखाना चाहिए? क्या .cpp है, यदि ऐसा है तो इसे कैसे दिखाना चाहिए?सी ++: अमूर्त विधि के साथ अमूर्त वर्ग बनाएं और उप-वर्ग में विधि को ओवरराइड करें

जावा में यह इस तरह दिखेगा:

abstract class GameObject 
{ 
    public abstract void update(); 
    public abstract void paint(Graphics g); 
} 

class Player extends GameObject 
{ 
    @Override 
    public void update() 
    { 
     // ... 
    } 

    @Override 
    public void paint(Graphics g) 
    { 
     // ... 
    } 

} 

// In my game loop: 
List<GameObject> objects = new ArrayList<GameObject>(); 
for (int i = 0; i < objects.size(); i++) 
{ 
    objects.get(i).update(); 
} 
for (int i = 0; i < objects.size(); i++) 
{ 
    objects.get(i).paint(g); 
} 

सी के लिए इस कोड का अनुवाद ++ मेरे लिए काफी है।

संपादित करें:

मैं कोड बनाया है, लेकिन मैं त्रुटि निम्न मिल जब मैं वस्तुओं से अधिक पुनरावृति करने की कोशिश:

Game.cpp:17: error: cannot allocate an object of abstract type ‘GameObject’ 
GameObject.h:13: note: because the following virtual functions are pure within ‘GameObject’: 
GameObject.h:18: note:   virtual void GameObject::Update() 
GameObject.h:19: note:   virtual void GameObject::Render(SDL_Surface*) 
Game.cpp:17: error: cannot allocate an object of abstract type ‘GameObject’ 
GameObject.h:13: note: since type ‘GameObject’ has pure virtual functions 
Game.cpp:17: error: cannot declare variable ‘go’ to be of abstract type ‘GameObject’ 
GameObject.h:13: note: since type ‘GameObject’ has pure virtual functions 

इस कोड के साथ:

vector<GameObject> gameObjects; 

for (int i = 0; i < gameObjects.size(); i++) { 
    GameObject go = (GameObject) gameObjects.at(i); 
    go.Update(); 
} 
+0

आपका "मेरे गेम लूप में" कोड है ... अपूर्ण, सर्वोत्तम रूप से। 'ऑब्जेक्ट्स' क्या है? यदि आपके पास पहले से कोई नहीं है, तो मैं दृढ़ता से अनुशंसा करता हूं कि शुरुआती किताबों में से एक [परिभाषित सी ++ पुस्तक गाइड और सूची] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide -और-सूची)। –

+0

आप हर्ब सटर के लेख, [वर्चुअल] (http://www.gotw.ca/publications/mill18) से भी परामर्श ले सकते हैं।एचटीएम), जो सी ++ में आभासी कार्यों और विरासत का उपयोग करते समय कई सर्वोत्तम प्रथाओं पर चर्चा करता है। –

उत्तर

20

जावा में, सभी विधियां virtual डिफ़ॉल्ट रूप से हैं, जब तक कि आप उन्हें final घोषित न करें। सी ++ में यह दूसरी तरफ है: आपको अपनी विधियों को स्पष्ट रूप से घोषित करने की आवश्यकता है virtual। और उन्हें शुद्ध वर्चुअल बनाने के लिए, आपको उन्हें 0 :-) पर "प्रारंभ" करने की आवश्यकता है यदि आपके वर्ग में शुद्ध वर्चुअल विधि है, तो यह स्वचालित रूप से सार बन जाता है - इसके लिए कोई स्पष्ट कीवर्ड नहीं है।

सी ++ में आपको मुश्किल संसाधन लीक से बचने के लिए हमेशा अपने बेस क्लास virtual के लिए विनाशक को परिभाषित करना चाहिए। तो मैं ने कहा कि नीचे दिए गए उदाहरण के लिए:

// GameObject.h 

class GameObject 
{ 
public: 
    virtual void update() = 0; 
    virtual void paint(Graphics g) = 0; 
    virtual ~GameObject() {} 
} 

// Player.h 
#include "GameObject.h" 

class Player: public GameObject 
{ 
public: 
    void update(); 

    void paint(Graphics g); 
} 

// Player.cpp 
#include "Player.h" 

void Player::update() 
{ 
    // ... 
} 

void Player::paint(Graphics g) 
{ 
    // ... 
} 
+0

क्या आप कृपया अपना संपादन देख सकते हैं? –

+2

@ मार्टिजन, आपके पास 'वेक्टर ' नहीं हो सकता है क्योंकि इससे इसके तत्वों को मूल्य के आधार पर स्टोर किया जाएगा, लेकिन 'GameObject', सार होने के कारण, कोई उदाहरण नहीं हो सकता है। पॉलिमॉर्फिक वस्तुओं को स्टोर करने के लिए आपको 'वेक्टर ' या अधिमानतः 'वेक्टर >' की आवश्यकता है। जेम्स मैकनेलिस के जवाब के लिए टिप्पणियां भी देखें। –

+0

यदि आपने पहले ही घोषित किया है, तो आपको GameObject.h में विधियों की घोषणा करने की आवश्यकता क्यों है? – HasaDev

6

सदस्य आधार वर्ग में कार्यों को virtual घोषित करने की आवश्यकता है। जावा में, सदस्य फ़ंक्शन डिफ़ॉल्ट रूप से आभासी होते हैं; वे सी ++ में नहीं हैं।

class GameObject 
{ 
public: 
    virtual void update() = 0; 
    virtual void paint(Graphics g) = 0; 
} 

virtual एक सदस्य समारोह आभासी बनाता है; = 0 सदस्य को शुद्ध आभासी कार्य करता है। यह वर्ग भी सार है क्योंकि इसमें कम से कम एक वर्चुअल सदस्य फ़ंक्शन है जिसमें कोई ठोस अंतिम ओवरराइडर नहीं है।

class Player : public GameObject 
{ 
public: 
    void update() { }   // overrides void GameObject::update() 
    void paint(Graphics g) { } // overrides void GameObject::paint(Graphics) 
} 

एक सदस्य समारोह एक आधार वर्ग में आभासी घोषित किया जाता है, तो यह किसी भी व्युत्पन्न वर्ग में स्वचालित रूप से आभासी है (आप में घोषणा में virtual रख सकते हैं:

फिर अपने व्युत्पन्न वर्ग (ते) में

यदि आप चाहें तो व्युत्पन्न कक्षा, लेकिन यह वैकल्पिक है)।

+0

और क्या मैं गेम ऑब्जेक्ट्स के वेक्टर में प्रत्येक तत्व के लिए 'अपडेट();' कह सकता हूं? –

+0

नहीं। आपको GameObject * का एक वेक्टर या shared_ptr या auto_ptr जैसे संबंधित वर्ग की आवश्यकता होगी। – Puppy

+0

हां, लेकिन यह इस तथ्य से निहित है कि 'GameObject' सार है। –

4

C++ में आप अपनी दिनचर्या पर कीवर्ड आभासी उपयोग करें, और उन्हें में =0; आवंटित। इसलिए जैसा:

class GameObject { 
public: 
    virtual void update()=0; 
    virtual void paint(Graphics g)=0; 

} 

एक 0 में यह पूर्ण रूप से अपने अपने वर्ग सार बनाता सौंपा के साथ एक आभासी विधि करने के बाद।

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