2016-02-13 141 views
1

從基類中覆蓋函數有點麻煩。從基類覆蓋函數

這是我的遊戲對象類:

namespace GameEngine { 
    class GameObject { 
    public: 
     virtual void render() { 
      std::cout << "Render Game Object" << std::endl; 
     } 
    }; 
} 

這是我的播放器類:

class Player : public GameEngine::GameObject { 
public: 
    void render() { 
     std::cout << "Render Player" << std::endl; 
    } 
}; 

在MainComponent.cpp我有GameObjects的載體,和我遍歷它們,使它們

Player player; 
vector<GameEngine::GameObject> gameObjects; 

void MainComponent::init() { 
    gameObjects.push_back(player); 

    gameLoop(); 
} 

void MainComponent::render() { 
    for(int i = 0; i < gameObjects.size(); i++) { 
     gameObjects[i].render(); 
    } 
} 

我希望這段代碼輸出「渲染播放器」,因爲gameObjects中的唯一對象ctor是播放器,但是它輸出「渲染遊戲對象」。有沒有一種方法可以強制GameObject向量中的Player對象使用Player渲染器而不是GameObject渲染器?

+0

這與重載無關。 'Player :: render' **覆蓋**'GameObject :: render'。 –

+0

@PeteBecker你說得對,我的錯誤,我編輯的職位,以反映這一點。 – shadowarcher

回答

2

如果一個派生類使用指針或引用到基部 類處理,在重寫虛擬函數的調用將調用在派生類中定義的 行爲。

您必須將指向基類的指針而不是基對象值存儲到向量中。

Player player; 
vector<GameEngine::GameObject*> gameObjects; 

void MainComponent::init() { 
    gameObjects.push_back(&player); 

    gameLoop(); 
} 

void MainComponent::render() { 
    for(int i = 0; i < gameObjects.size(); i++) { 
     gameObjects[i]->render(); 
    } 
} 
1

下面是說明了同樣的問題的代碼的簡化版本:

GameEngine::GameObject object = player; 
object.render(); 

問題是player對象通過切掉player的基本部分而被轉換爲GameObject。所以存儲的是GameObject,而不是Player對象。

的解決方案是使用指針或引用,而不是一個對象:

GameEngine::GameObject *ptr = &player; 
ptr->render(); 

你需要做同樣的事情在gameObjects:而不是存儲GameObject應該指針存儲GameObject類型的對象:

std::vector<GameEngine::GameObject*> gameObjectPointers; 
gameObjectPointers.push_back(&player); 
gameObjectPointers[0]->render(); 

一旦你這樣做,你必須密切關注對象的生命週期。如果playergameObjectPointers之前被破壞,則gameObjectPointers[0]指向一個不再存在的對象,並且使用它將使不好的事情發生。

1

有沒有一種方法可以強制GameObject向量中的Player對象使用Player渲染器而不是GameObject渲染器?

No.你跟vector<GameEngine::GameObject> gameObjects;類型聲明vector,所以基類的實例將被存儲在vector。而當gameObjects.push_back(player);,對象將是slicing copied,沒有Player

您可以將基類指針到vector,並更好地使用智能指針,以避免手動內存管理CHINESE。例如:

vector<unique_ptr<GameEngine::GameObject>> gameObjects; 

void MainComponent::init() { 
    gameObjects.emplace_back(new Player); 
    // or gameObjects.push_back(unique_ptr(new Player)); 
    gameLoop(); 
} 

void MainComponent::render() { 
    for(int i = 0; i < gameObjects.size(); i++) { 
     gameObjects[i]->render(); 
    } 
}