[英]How do I store different classes in a single vector?
所以我有一個載滿我游戲所有物體的載體; 玩家對象,敵人對象,牆壁等等......向量中的所有東西都是Framework
子代,所以我創建了向量類型Framework
因為這是它們與通用數據類型最接近的東西。
問題是它沒有從它存儲的對象運行重寫的函數。 所以我用谷歌搜索它,通過將它們存儲為Framework
,顯然我是對象切片。 那么我的問題是,如何將所有這些對象存儲在一個列表中?
僅供參考,這是調用假定被覆蓋的函數的地方。
for (vector<Framework>::iterator num = gameObjects.begin(); num != gameObjects.end(); ++num)
{
//The current thing
Framework currentObject = *num;
currentObject.frameEvent();
currentObject.frameEndEvent();
currentObject.drawEvent();
}
提前致謝。
您必須存儲指針( Framework*
)或std::shared_ptr< Framework >
(可能是std::unique_ptr< Framework >
)實例。 這允許使用虛擬調用和后期綁定 - 這意味着當您引用對象時,將在運行時確定要調用的正確函數。 不要忘記讓你的功能virtual
然后,你的代碼(以類似的方式)
for (vector< Framework* >::iterator num = gameObjects.begin(); num != gameObjects.end(); ++num)
{
Framework* currentObject = *num;
currentObject->frameEvent();
currentObject->frameEndEvent();
currentObject->DrawEvent();
}
但是,我推薦這樣的(需要c ++ 11)
vector< std::unique_ptr< Framework > > gameObjects;
...
for (auto & currentObject : gameObjects)
{
currentObject->frameEvent();
currentObject->frameEndEvent();
currentObject->DrawEvent();
}
無論使用何種類型,最后一個(循環范圍)都應該有效(您可以使用普通指針或shared_ptr或unique_ptr,如示例所示)。
如果您對使用unique_ptr
感興趣,請注意,為了將這些存儲在std::vector
,您必須使用std::move
,因為只能有一個std::unique_ptr
實例(顧名思義)。 如有問題請咨詢此答案 。
您必須使用std::vector<Framework*>
或std::vector<std::unique_ptr<Framework>>
(或您選擇的智能指針)來避免對象切片。
代碼示例:
std::vector<std::unique_ptr<Framework>> gameObjects;
gameObjects.push_back(std::make_unique<Player>(/**/));
gameObjects.push_back(std::make_unique<Wall>(/**/));
接着
for (auto& currentObject : gameObjects)
{
currentObject->frameEvent();
currentObject->frameEndEvent();
currentObject->drawEvent();
}
存儲指向Framework
指針並使用多態。
// Base class
class Framework {
// Make pure virtual if nothing is done here.
virtual void frameEvent(); // = 0;
// To ensure the derived instances are deleted properly.
virtual ~Framework(); // = default;
};
// Some specialized class
class SomeObject : public Framework {
void frameEvent() override; // C++11 style override.
};
std::vector<std::unique_ptr<Framework>> objects;
// Add a new SomeObject to the list
objects.emplace_back(new SomeObject());
嗯,直接的答案是 - 你沒有。 或者您將獲得已經遇到的對象切片。 您需要使用C ++的多態能力並將對象的公共接口存儲在向量中。 稍后,您可以通過根據實際對象類型調用具有不同實現的接口函數來調用所需的行為。
您必須在Framework
創建frameEvent
, frameEndEvent
和drawEvent
虛擬。 然后,將std::shared_ptr
存儲在向量中:
std::vector<std::shared_ptr<Framework>> objects;
objects.push_back(new GameObject());
for (vector<Framework>::iterator num = gameObjects.begin(); num != gameObjects.end(); ++num)
{
//The current thing
const Framework& currentObject = **num; // reference, don't copy anything if you don't need to
currentObject.frameEvent();
currentObject.frameEndEvent();
currentObject.drawEvent();
}
請注意, 只要不使用需要復制元素的操作,就可以將unique_ptr
存儲在向量中 。
另一個選擇,如果你不能使函數虛擬並知道你正在處理什么類型的對象,你可以先拋出然后調用非虛函數:
const PlayerObject& player = static_cast<const PlayerObject&>(*objects[0]);
player.frameEvent();
player.frameEndEvent();
player.drawEvent();
您需要存儲指向對象的指針 。 如果您有C++11
那么理想情況下您將使用std :: unique_ptr存儲它們(假設您有一個主矢量 )。
C ++ 03
std::vector<Framework*> gameObjects;
for(std::vector<Framework*>::iterator num = gameObjects.begin();
num != gameObjects.end(); ++num)
{
(*num)->frameEvent();
(*num)->frameEndEvent();
(*num)->drawEvent();
}
C ++ 11
std::vector<std::unique_ptr<Framework>> gameObjects;
for(auto& num: gameObjects)
{
num->frameEvent();
num->frameEndEvent();
num->drawEvent();
}
將指針存儲在向量中,而不是實際實例中。
另一種可能更快的方法是將它們存儲在單獨的向量中。 由於更高的緩存效率,它可以快50倍。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.