2010-05-29 175 views
14

如何用C++創建一個抽象類,並使用一些我想在子類中重寫的抽象方法? .h文件應該怎麼看?有沒有.cpp,如果是這樣,它應該看起來如何?C++:用抽象方法創建抽象類並重寫子類中的方法

在Java中它是這樣的:

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); 
} 

翻譯這段代碼C++是對我來說足夠。

編輯:

我創建的代碼,但是當我嘗試遍歷對象我得到以下錯誤:

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

你的「在我的遊戲循環」代碼是......不完整,至多。什麼是「對象」?如果你還沒有,我強烈建議從[The Definitive C++ Book Guide and List]獲得一本初學者書籍(http://stackoverflow.com/questions/388242/the-definitive-c-book-guide -and列表)。 – 2010-05-29 22:54:37

+0

您也可以諮詢Herb Sutter的文章[虛擬性](http://www.gotw.ca/publications/mill18。htm),其中討論了在C++中使用虛函數和繼承時的許多最佳實踐。 – 2010-05-29 22:59:53

回答

20

在Java中,默認情況下所有方法都是virtual,除非您聲明它們爲final。在C++中,這是相反的:你需要明確聲明你的方法virtual。爲了使它們成爲純虛擬的,你需要將它們初始化爲0 :-)如果你的類中有一個純虛擬方法,它會自動變成抽象的 - 沒有明確的關鍵字。

在C++中,您應該(幾乎)總是爲您的基類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

你可以看看我的編輯嗎? – 2010-05-30 15:15:52

+2

@Martijn,你不能有一個'vector ',因爲它會按值存儲它的元素,但是'GameObject'是抽象的,可以沒有實例。您需要一個'vector '或最好是一個'vector >'來存儲多態對象。另請參閱James McNellis的回答。 – 2010-05-30 15:31:01

+0

爲什麼你需要在GameObject.h中聲明方法,如果它們已經聲明的話? – HasaDev 2016-09-13 19:55:08

6

成員函數需要在基類中聲明爲virtual。在Java中,成員函數默認是虛擬的;他們不在C++中。

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在聲明:

在派生類(ES)

然後派生類,如果你願意,但它是可選的)。

+0

我可以爲GameObject的向量中的每個元素調用'update();'嗎? – 2010-05-29 22:54:22

+0

不需要。您需要一個GameObject *或像shared_ptr或auto_ptr這樣的相關類的向量。 – Puppy 2010-05-30 11:15:42

+0

是的,但這是暗示'GameObject'是抽象的。 – 2010-05-30 13:51:26

4

在C++中使用關鍵字虛擬您的程序,並指定=0;放進去。像這樣:

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

} 

虛擬方法的0分配給它自動使您的類抽象。