C++ 從基礎到精通 — 第 10 講
選擇STL容器和可選
該部落格上撰寫的文章是出於教學目的而創建的。 另外,文章中的資訊可能不正確,請謹慎。
遊戲中有不同類型的數據,例如隊伍列表、怪物搜尋、產生隊列和擊殺記錄。 所有資料都可以用單一向量解析,但如果您使用適合目的的資料結構,程式碼會更清晰。
vector
std::vector是一個使用連續記憶體的動態數組。
std::vector<int> damages;
damages.reserve(10);
damages.push_back(10);
damages.emplace_back(20);
for (int damage : damages)
{
std::cout << damage << '\n';
}
該元素是[]或者at()方法。 at()檢查範圍,但是[]沒有檢查。
如果向量的容量不足,則會透過建立新的更大記憶體並移動現有元素來進行重新分配。 此時,指向現有元素的指標、引用和迭代器可能會失效。
unordered_map
若要按項目 ID 快速尋找項目,請使用哈希表。std::unordered_map這很適合你。
std::unordered_map<int, Item> itemDatabase;
itemDatabase.emplace(1, Item{1, "Sword", 100});
auto iter = itemDatabase.find(1);
if (iter != itemDatabase.end())
{
std::cout << iter->second.name << '\n';
}
find()如果失敗end()返回。 在沒有檢查是否找到迭代器的情況下,不應取消引用迭代器。
佇列和堆疊
佇列是一種 FIFO 結構,先進入的值先出現。它非常適合生成隊列。
if (!spawnQueue.empty())
{
auto monster = spawnQueue.front();
spawnQueue.pop();
}
堆疊是一個 LIFO 結構,其中最後一個值首先出現。它可用於記錄或撤銷最近的擊殺。
if (!killHistory.empty())
{
int lastMonsterId = killHistory.top();
killHistory.pop();
}
pop 不傳回值。您必須先使用 front 或 top 取得值,然後呼叫 pop。
optional
如果可能沒有搜尋結果,而不是一個特殊的錯誤值std::optional可以使用。
std::optional<Item> FindItem(int id) const
{
auto iter = itemDatabase.find(id);
if (iter == itemDatabase.end())
{
return std::nullopt;
}
return iter->second;
}
if (auto item = FindItem(1))
{
std::cout << item->name << '\n';
}
傳回類型表示可能有也可能沒有值。 盲目回答空選項value()你不應該打電話。您必須先檢查是否存在。
選擇資料結構的標準不是時尚,而是預期用途。 有序列表可以表示為向量,鍵搜尋表示為 unordered_map,等待順序表示為佇列,最近記錄表示為堆疊,並且缺少值表示為可選。